2

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

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

失败是内部异常中WebException的状态SendFailure和套接字错误。ConnectionReset (10054)错误是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,我们的测试证书只是在网站的目录中。我们不会直接从证书存储中提取它(除非我们不完全了解从文件加载证书时的工作原理)。

4

2 回答 2

0

在您收到错误之前是否有任何形式的延迟(例如,可能表明发生超时的事情)?

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

于 2013-09-23T22:57:31.203 回答
0

您可能通过代理连接互联网检查您的 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;

返回请求.GetResponse();

于 2015-11-23T20:14:47.473 回答