HttpWebRequest.GetResponse()返回404错误

时间:2015-02-08 17:26:47

标签: c# asp.net-mvc iis ssl web-config

我有一些代码调用HttpWebRequest的GetResponse()方法从URL检索HTML并将其返回给调用方法。

这在我的开发和QA环境中运行得非常好但是现在我已经将它上传到我的UAT服务器,我不断收到以下错误:

远程服务器返回错误:(404)Not Found。

Dev / QA和UAT之间的主要区别在于UAT使用基于SSL / HTTPS的URL,而Dev / QA使用HTTP。我介绍了以下代码行,以帮助我进一步发展:

ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);

其中AcceptAllCertifications总是返回true但我仍然得到404错误。

我以前遇到此错误的人只能通过确保用于HttpWebRequest的URI最后没有斜杠来解决问题(请参阅:Simple HttpWebRequest over SSL (https) gives 404 Not Found under C#)但这不会对我不同。

我现在尝试了这篇文章的建议(参见:HttpWebResponse returns 404 error),我在页面上呈现异常。这绕过了黄色警告屏幕并给了我更多信息,包括它试图从中获得响应的URL。但是,当我将URL复制并粘贴到我的浏览器中时,它可以很好地工作并在页面上呈现HTML。因此,我很高兴在GetResponse调用中使用了正确的URL。

有没有人对可能导致我这种悲伤的原因有任何想法?如上所述,在我使用SSL的UAT服务器上似乎只是一个问题。

以下是我的协助代码:

public static string GetHtmlValues()
    {

        var webConfigParentUrlValue = new Uri(ConfigurationManager.AppSettings["ParentUrl"]);

        var destinationUrl = HttpContext.Current.Request.Url.AbsoluteUri;

        var path = "DestinationController" + "/" + "DestinationAction" + "?destinationUrl=" + destinationUrl;

        var redirect = new Uri(webConfigParentUrlValue, path).AbsoluteUri;
        ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
        var request = (HttpWebRequest)WebRequest.Create(redirect);

//Ensures that if the user has already signed in to the application,
// their authorisation is carried on through to this new request
        AttachAuthorisedCookieIfExists(request);

        HttpWebResponse result;

        try
        {
            result = (HttpWebResponse)request.GetResponse();
        }
        catch (WebException ex)
        {
            result = ex.Response as HttpWebResponse;
        }

        String responseString;

        using (Stream stream = result.GetResponseStream())
        {
            StreamReader reader = new StreamReader(stream, Encoding.UTF8);
            responseString = reader.ReadToEnd();
        }

        return responseString;
    }

在页面上呈现错误的更多细节:

Error as it is rendered on page

2 个答案:

答案 0 :(得分:0)

我遇到了类似的情况,但是出现了不同的错误消息。我的问题原来是我的UAT环境是带有.NET 4.5的Windows 2008。在此环境中,SSL握手/检测的执行方式与大多数Web浏览器不同。所以我在Web浏览器中看到URL没有错误地呈现,但我的应用程序会生成错误。我的错误消息包括"基础连接已关闭:发送"发生意外错误。这可能是你的问题。

我的解决方案是强制更改协议。我检测到特定错误,然后强制更改我的应用程序的安全协议,然后重试。

这是我使用的代码:

catch (Exception ex)
{
    if(ex.Message.Contains("The underlying connection was closed: An unexpected error occurred on a send."))
    {
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
        // retry the retrieval
    }
}

答案 1 :(得分:0)

我终于找到了解决问题的方法......

让我走上正确轨道的第一条线索是IIS中404错误中显示的错误物理路径。事实证明,这个不正确的物理路径已映射到我的IIS设置中的另一个站点。这个特别自然也具有约束力;如您所知,端口443是https的默认端口。

现在查看我尝试传递给HTTPWebRequest.GetResponse()方法的网址,它看起来像这样:

https://www.my-web-site.com

考虑到这一点,当此应用程序在SSL的范围内托管在IIS上时,错误发生如下:

  1. 代码输入上述方法GetHtmlValues()
  2. 代码从web.config文件获取https://www.my-web-site.com
  3. https://www.my-web-site.com
  4. 请求回复
  5. 此时,由于没有指定端口且应用程序现在在开放的互联网上,它会尝试从https://www.my-web-site.com:443
  6. 获得响应
  7. 问题是,我的应用程序不是通过端口443上的IIS托管的。这里有一个不同的应用程序。随后,由于在端口443上找不到页面,因此产生404错误。
  8. 现在解决方案......

    1. 在IIS中查找我的应用程序所在的端口。我们说端口16523。
    2. 然而,之前在我的web.config中,我的ParentUrl键被赋予了https://www.my-web-site.com的十分值,这将被更改为http://www.my-web-site.com:16523
    3. 请注意https如何变为http并且最后指定了端口号。现在,当应用程序尝试获取响应时,它不再使用默认的ssl端口,因为指定了正确的端口。