HttpWebRequest.GetResponse() 返回 404 错误
HttpWebRequest.GetResponse() returning 404 Error
我有一些代码调用 HttpWebRequest 的 GetResponse() 方法从 URL 检索 HTML 并将其 return 到调用方法。
这在我的开发和 QA 环境中一直运行良好,但现在我已经将它上传到我的 UAT 服务器,我不断收到以下错误:
远程服务器 return 出现错误:(404) 未找到。
Dev/QA 和 UAT 之间的主要区别是 UAT 使用基于 SSL/HTTPS 的 URLs 而 Dev/QA 使用 HTTP。我引入了以下代码行来帮助我进一步进步:
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
其中 AcceptAllCertifications 总是 returns true 但我仍然收到 404 错误。
我知道以前遇到此错误的人已经能够通过仅确保用于 HttpWebRequest 的 URI 末尾没有斜线来解决问题(参见:),但这确实对我没有影响。
我现在已经尝试了在此 post(参见:)中提出的建议,我在该页面上呈现了异常。这绕过了 yellow-warning 屏幕并为我提供了更多信息,包括它试图从中获得响应的 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;
}
页面上呈现的错误的更多详细信息:
我运行遇到了类似的情况,但错误信息不同。我的问题原来是我的 UAT 环境是 Windows 2008 with .NET 4.5。在此环境中,SSL handshake/detecting 的执行方式与大多数 Web 浏览器不同。所以我看到 URL 在 Web 浏览器中没有错误地呈现,但我的应用程序会生成错误。我的错误消息包括 "The underlying connection was closed: An unexpected error occurred on a send"。这可能是你的问题。
我的解决方案是强制更改协议。我检测到特定错误,然后强制更改应用程序的安全协议并重试。
这是我使用的代码:
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
}
}
我终于找到了解决问题的方法...
使我走上正轨的第一个线索是 IIS 的 404 错误中显示的物理路径错误。事实证明,这个不正确的物理路径被映射到我的 IIS 设置中的另一个站点。这个特殊性自然也有约束力;端口 443。您可能知道,端口 443 是 https 的默认端口。
现在看看我试图传递给 HTTPWebRequest.GetResponse()
方法的 URL,它看起来像这样:
https://www.my-web-site.com
考虑到这一点,当此应用程序托管在 SSL 范围内的 IIS 上时,出现如下错误:
- 代码进入上述方法
GetHtmlValues()
- 代码从 web.config 文件中获取
https://www.my-web-site.com
- 请求
https://www.my-web-site.com
作出回应
- 此时,由于没有指定端口并且应用程序现在已经在开放的互联网上,它会尝试从
https://www.my-web-site.com:443
获得响应
- 问题是,我的应用程序不是通过端口 443 上的 IIS 托管的。这里有一个不同的应用程序。随后,由于在443端口找不到该页面,产生了404错误。
现在是解决方案...
- 在 IIS 中查找,我找到了我的应用程序所在的端口。假设端口 16523.
- 而之前在我的 web.config 中,我的 ParentUrl 密钥被标记为
https://www.my-web-site.com
,这将更改为 http://www.my-web-site.com:16523
请注意 https
是如何变成 http
并且在末尾指定端口号的。现在,当应用程序尝试获取响应时,它不再使用默认的 ssl 端口,因为指定了正确的端口。
我有一些代码调用 HttpWebRequest 的 GetResponse() 方法从 URL 检索 HTML 并将其 return 到调用方法。
这在我的开发和 QA 环境中一直运行良好,但现在我已经将它上传到我的 UAT 服务器,我不断收到以下错误:
远程服务器 return 出现错误:(404) 未找到。
Dev/QA 和 UAT 之间的主要区别是 UAT 使用基于 SSL/HTTPS 的 URLs 而 Dev/QA 使用 HTTP。我引入了以下代码行来帮助我进一步进步:
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
其中 AcceptAllCertifications 总是 returns true 但我仍然收到 404 错误。
我知道以前遇到此错误的人已经能够通过仅确保用于 HttpWebRequest 的 URI 末尾没有斜线来解决问题(参见:),但这确实对我没有影响。
我现在已经尝试了在此 post(参见:)中提出的建议,我在该页面上呈现了异常。这绕过了 yellow-warning 屏幕并为我提供了更多信息,包括它试图从中获得响应的 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;
}
页面上呈现的错误的更多详细信息:
我运行遇到了类似的情况,但错误信息不同。我的问题原来是我的 UAT 环境是 Windows 2008 with .NET 4.5。在此环境中,SSL handshake/detecting 的执行方式与大多数 Web 浏览器不同。所以我看到 URL 在 Web 浏览器中没有错误地呈现,但我的应用程序会生成错误。我的错误消息包括 "The underlying connection was closed: An unexpected error occurred on a send"。这可能是你的问题。
我的解决方案是强制更改协议。我检测到特定错误,然后强制更改应用程序的安全协议并重试。
这是我使用的代码:
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
}
}
我终于找到了解决问题的方法...
使我走上正轨的第一个线索是 IIS 的 404 错误中显示的物理路径错误。事实证明,这个不正确的物理路径被映射到我的 IIS 设置中的另一个站点。这个特殊性自然也有约束力;端口 443。您可能知道,端口 443 是 https 的默认端口。
现在看看我试图传递给 HTTPWebRequest.GetResponse()
方法的 URL,它看起来像这样:
https://www.my-web-site.com
考虑到这一点,当此应用程序托管在 SSL 范围内的 IIS 上时,出现如下错误:
- 代码进入上述方法
GetHtmlValues()
- 代码从 web.config 文件中获取
https://www.my-web-site.com
- 请求
https://www.my-web-site.com
作出回应
- 此时,由于没有指定端口并且应用程序现在已经在开放的互联网上,它会尝试从
https://www.my-web-site.com:443
获得响应
- 问题是,我的应用程序不是通过端口 443 上的 IIS 托管的。这里有一个不同的应用程序。随后,由于在443端口找不到该页面,产生了404错误。
现在是解决方案...
- 在 IIS 中查找,我找到了我的应用程序所在的端口。假设端口 16523.
- 而之前在我的 web.config 中,我的 ParentUrl 密钥被标记为
https://www.my-web-site.com
,这将更改为http://www.my-web-site.com:16523
请注意 https
是如何变成 http
并且在末尾指定端口号的。现在,当应用程序尝试获取响应时,它不再使用默认的 ssl 端口,因为指定了正确的端口。