底层连接 Closed on HttpWebRequest POST On production Server

Posted

技术标签:

【中文标题】底层连接 Closed on HttpWebRequest POST On production Server【英文标题】:underlying connection Closed on HttpWebRequest POST On production Server 【发布时间】:2010-11-23 18:53:00 【问题描述】:

我收到“底层连接已关闭:连接意外关闭”。尝试在生产服务器上使用 HttpWebRequest 类进行 POST 时出错,在我的开发机器上它工作正常。

我最初尝试使用 WebClient 类,但我切换到 HttpWebRequest 以尝试我在研究问题时发现的一些建议(例如将 KeepAlive 设置为 false,PreAuthenticate true 和 ProtocolVersion 到 1.0)。

由于它只发生在生产服务器上,我猜它可能与 IIS 有关。

这是我的代码

        HttpWebRequest HttpWReq =
        (HttpWebRequest)WebRequest.Create(webURL);

        ASCIIEncoding encoding=new ASCIIEncoding();
        Byte[] postbytes = Encoding.ASCII.GetBytes(data);

        HttpWReq.Headers.Add("Authorization",
                  String.Format("Basic 0", authstring));
        HttpWReq.KeepAlive = false;
        HttpWReq.PreAuthenticate = true;  
        HttpWReq.Credentials = CredentialCache.DefaultCredentials;
        HttpWReq.UseDefaultCredentials = true;
        HttpWReq.ProtocolVersion = HttpVersion.Version10;


        HttpWReq.Method = "POST";
        HttpWReq.ContentType = "application/x-www-form-urlencoded";
        HttpWReq.ContentLength = postbytes.Length;

        Stream newStream = HttpWReq.GetRequestStream();
        newStream.Write(postbytes, 0, postbytes.Length);
        newStream.Close();

以及我最初尝试使用 WebClient 类的代码

  /*  WebClient client = new WebClient();
    client.Headers.Add("Authorization",
              String.Format("Basic 0", authstring));
    client.Headers.Add("Content-Type",
                       "application/x-www-form-urlencoded");
    client.UseDefaultCredentials = true;
    System.Net.ServicePointManager.Expect100Continue =  false;

     Byte[] postbytes = Encoding.ASCII.GetBytes(data);

    byte[] resp = client.UploadData(webURL, "POST", postbytes); */

谢谢,任何帮助将不胜感激。

编辑:

使用 fidler 检查标题我得到了这个信息

POST [MyWebSite] HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-            flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
Referer: [MyWebSite]
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; GTB6.5; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322)
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: [MyHost]
Content-Length: 188
Connection: Keep-Alive
Pragma: no-cache
Cookie: __utma=62854692.1254171006.1276438746.1289273298.1289317993.21; __utmz=62854692.1277743505.3.3.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=yeled; ASPSESSIONIDQQQRCRAT=ANNHGGNBNOFNFCLHPBEJIMLC

__VIEWSTATE=%2FwEPDwUKMjA0OTM4MTAwNGRktZi0IsIUo6MOCYTxun8p8Po4AWeTtipGZ4L9%2FkY3KZU%3D&__EVENTVALIDATION=%2FwEWAgLHhsXtBwK14deQBbiFCpWBnsp%2BicqBy%2FNXAkhuVDX9WF1jZayRuTgPc3Ov&btnTest=Test

EDIT2

如果将目标框架(我使用一个新项目进行测试)设置为 2.0(我没有测试框架的每个版本),它就可以工作。我猜.net 在.net 4.0 中处理安全性的方式不同。这不是一个解决方案,但我希望有人可以使用该信息来帮助我解决这个问题。

【问题讨论】:

【参考方案1】:

这是一个保持活动状态和 100 次继续的经典示例。到目前为止,我看到的所有案例都是由于这个问题,所以我想说你走在正确的轨道上。

首先,使用 Fiddler 获取请求原始视图以查看您的请求是什么样的。我打赌你那里有Expect:100-continue。所以试试HttpWReq.Expect="";

您似乎正在使用 Windows 身份验证,请尝试将其关闭以查看是否会出现问题 - 显然您不能一直关闭它,只需查看行为是什么。

更新

首先,我几乎可以肯定这与您发送的请求不同。这是告诉我这不是您的 HttpWebRequest 的用户代理:

Mozilla/4.0(兼容;MSIE 7.0; 视窗 NT 5.1;三叉戟/4.0; GTB6.5; InfoPath.2; .NET CLR 2.0.50727; 。网 CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322)

还有视图状态让我相信这只是来自浏览的另一个请求。也不是 1.1 的协议。

我还注意到您没有得到可能与此有关的响应。您需要调用 request.GetResponseStream 并阅读它。

【讨论】:

我尝试设置 HttpWReq.Expect="" 但似乎没有什么不同。我不确定要查找 fiddler 什么,但我正在使用该信息更新我的帖子。 感谢您的帮助。我尝试获取响应 HttpWebResponse response = (HttpWebResponse)HttpWReq.GetResponse();但它正在返回(401)未经授权。关于 Fidler 数据,也许我正在查看错误信息,即发布的数据来自标题的原始视图(在检查器选项卡下)。 我创建了一个新的空项目,用于测试,当我将目标框架设置为 2.0 并且它工作时,它似乎在 4.0 中处理方式有所不同。 -我正在使用该信息更新我的原始帖子。【参考方案2】:

这似乎是一个权限问题。如果我将 IIS 上的应用程序池帐户从 ASP.net 更改为 NTService,则它会正确发布。我将尝试找出它需要哪些特定权限,看看我是否可以将其授予 asp.net 帐户。

更新

我不确定它到底做了什么,但是在更改了在服务器上运行的用户帐户的一些写入权限并重新启动它之后,它现在可以工作了。

最后我能够使用 WebClient 包装类。

    WebClient client = new WebClient();

    client.Headers.Add("Authorization",
                          String.Format("Basic 0", authstring));
    client.Headers.Add("Content-Type",
                       "application/x-www-form-urlencoded");
    client.UseDefaultCredentials = true;

    byte[] resp = client.UploadData(url, "POST", postbytes);

【讨论】:

以上是关于底层连接 Closed on HttpWebRequest POST On production Server的主要内容,如果未能解决你的问题,请参考以下文章

The WebSocket session [0] has been closed and no method (apart from close()) may be called on a clos

Android on Drawer Closed Listener

(转)Android 从底层实现让应用杀不死失效Closed

Python ValueError: IO operation on closed file

思考Ruby On Rails的底层代码(Ruby on Rails 開發秘籍 | Ruby on Rails 快速入門)

Jupyter Notebook Logging ValueError: I/O Operation on Closed File