问题
I'm getting the "The underlying connection was closed: The connection was closed unexpectedly." error while trying to POST using the HttpWebRequest class on the production server, on my dev machine it works fine.
I originally tried using the WebClient class but I switched to the HttpWebRequest to try some of the suggestions I found while researching the issue (such as setting KeepAlive to false, PreAuthenticate true and ProtocolVersion to 1.0).
Since it's only happening on the production server, i'm guessing that it might have something to do with IIS.
Here's my code
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();
And the code I originally tried using the WebClient class
/* 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); */
Thanks, Any help would be appreciated.
EDIT:
Using fidler to examine the header I got this info
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
If set the Target Framework (I used a new project for testing) to 2.0 (I didn't test every version of the framework) it works. I'm guessing that .net handles the security differently in .net 4.0. This isn't a solution, but I'm hoping somebody could use that info to help me resolve this.
回答1:
This is a classic example of keep alive and 100-continue. All cases I have seen so far were due to this issue so I would say you are on the right track.
First of all, use Fiddler to get the request raw view to see what your request looks like. I bet you have Expect:100-continue
in there. so try HttpWReq.Expect="";
It seems that you are using Windows authentication, try turning that off to see if this could be making issues - obviously you cannot turn that off all the time,just see what behaviour is.
UPDATE
First of all, I am almost sure that this is not the same request you are sending. This is the user agent which tells me it is not your HttpWebRequest:
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)
Also there is view state which makes me believe this is just another request from browse. Also not protocol which is 1.1.
I also noticed that you are not getting the response which might to do with it. You need to call request.GetResponseStream and read it.
回答2:
It appears to be a permissions issue. If I change the application pool's account on IIS from ASP.net to NTService it then posts correctly. I'm going to try and find out which specific permission it needs and see if I can grant that to the asp.net account.
UPDATE
I'm not sure what exactly did it, but after changing some of the write permissions for the user account that's running on the server and restarting it, it is now working.
In the end I was able to use the WebClient wrapper class.
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);
来源:https://stackoverflow.com/questions/4259639/underlying-connection-closed-on-httpwebrequest-post-on-production-server