为什么 HttpWebRequest.GetResponse() 在 IIS 下的 ASP.NET 页面中失败

本文关键字:NET ASP 失败 下的 IIS GetResponse HttpWebRequest 为什么 | 更新日期: 2023-09-27 18:30:41

我为我们的一位开发人员构建了一组API,供其在我们的Web应用程序中使用。我在 .NET 4.0 类库项目中执行此操作,并编写了集成测试,以确保 API 与后端服务正确集成。在集成测试(单元测试项目)以及控制台应用程序中,API 正常工作并返回所有预期结果。但是,当我们从在 IIS 下运行的 ASP.NET 网页执行相同的 API 时,API 在以下代码行中失败:

using (HttpWebResponse response = (HttpWebRequest)request.GetResponse())

失败是内部异常中状态为 SendFailure 和套接字错误为 ConnectionReset (10054)WebException。错误是 The underlying connection was closed: An unexpected error occurred on a send 。这也是使用HTTPS(因此是X509)。

我已经知道这实际上是发出请求的时间,但我正在尝试查明 IIS 环境的不同之处,这会阻止流能够通过网络写入字节。我知道这实际上是 Web 服务服务器在我们有机会发送数据之前关闭连接,但我想再次敦促,同样的 API 在集成或单元测试或控制台应用程序下工作正常。

我已经用尽了互联网上尽可能多的相关文章和帖子,包括广泛的 Msdn 文档,例如检查与证书相关的内容、修改 HTTP 标头服务点属性。我真的很茫然,因为代码并不复杂,我已经写了太多次 Web 请求代码来计数,但这里是:

private string ExecuteServiceMessages(Uri serviceUrl, X509Certificate clientCertificate, string requestBody)
{
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceUrl);
    request.ClientCertificates.Add(clientCertificate);
    request.Date = DateTime.Now;
    request.Method = WebRequestMethods.Http.Post;
    request.ContentType = MediaTypeNames.Text.Xml;
    request.UserAgent = "******";
    request.KeepAlive = false;
    using (Stream requestStream = request.GetRequestStream())
    using (StreamWriter writer = new StreamWriter(requestStream))
    {
        writer.Write(requestBody);
        writer.Close();
    }
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    using (Stream responseStream = response.GetResponseStream())
    using (StreamReader reader = new StreamReader(responseStream))
    {
        string data = reader.ReadToEnd();
        reader.Close();
        return data;
    }
}

证书由 X509Certificate.CreateFromCertFile 加载,我们的测试证书就在网站的目录中。我们不会直接从证书存储中提取它(除非我们不完全了解从文件加载证书时的工作方式)。

为什么 HttpWebRequest.GetResponse() 在 IIS 下的 ASP.NET 页面中失败

在收到错误之前是否有任何类型的延迟(例如,可能指示正在发生超时的内容)?

当框架尝试验证该证书时,会发生很多事情。 它可能执行的操作之一(取决于您使用的 X509 策略)是检查证书吊销列表,这需要连接到互联网。 当我们尝试在互联网访问受限的环境中运行代码时,这已经咬了我们几次 - 它旋转了 60 秒,然后返回您看到的错误(不是很有帮助)。 如果是这样,您可以将 CRL 策略更改为脱机,或者编辑主机文件并覆盖 DNS,以便使用环回地址执行 CRL 检查 - 它将失败,但至少您不会超时。

您可能正在通过代理连接互联网,请检查您的 IE 局域网设置。在 C# 中,您需要添加代理设置

 var request = (HttpWebRequest)WebRequest.CreateHttp(url);
                    WebProxy proxy = new WebProxy("http://127.0.0.1:8888", true);
                    proxy.Credentials = new NetworkCredential("ID", "pwd", "Domain");
                    request.Proxy = proxy;
                    request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
                    request.Timeout = 1000 * 60 * 5;
                    request.Method = method;

退货请求。获取响应();