« Upgrade are successful | Main | Step aside Sun »
.NET bug for large web service requests

There's a bug in both the 1.0 and 1.1 versions of the .NET frameworks that can cause web service calls to throw a WebException with HTTP error 400 Bad Request. This bug comes up when posting a more than 48 kilobytes of data to a web service protected by HTTP authentication. In my case, I was working on a WinForms client that uploads image files to a web service. The problem was hard to track down, but eventually I was able to find a workaround that works well enough until a fix comes out.

When using HTTP authentication for a web service, the proxy class generated by the Web Reference feature in VS or the wsdl.exe tool will make requests with no authentication header until the server responds with a 401 Unauthorized error. The 401 response lets the proxy class know which authentication mechanisms the server supports, such as Basic or Digest. If you're supplied the proxy class with a valid NetworkCredential, the proxy class will automatically retry the request using those credentials for one of the supported authentication mechanisms. This all happens transparently to the client application; you won't see that 401 unless you're packet sniffing.

The bug happens only on the first request to the server when the proxy class doesn't yet know which authentication mechanisms the server supports. Since the proxy class doesn't know which authentication mechanism to use, it sends the first request without authentication. IIS buffers the first 48 kilobytes of the request before it hands off to the ASP.NET handler and, when it does, ASP.NET refuses the request since it wasn't authenticated. Despite receiving a 401 Unauthorized error, the client's proxy class keeps sending data to the server which then causes IIS to send back a 400 Bad Request error. The 400 gets thrown as a WebException and the call fails.

Now for the workaround. If the first web service request your proxy class makes is going to be more than 48 kilobytes and the server is using HTTP authentication: Set the proxy class's Credentials property and set the PreAuthenticate property to true then call a no-op method or any other small method on your web service before the big request gets made. The small web service call will initially result in a 401 which will let the proxy class know which authentication mechanisms the server supports. With PreAuthenticate set to true, the proxy class won't make the same mistake twice and all subsequent requests will work fine with authentication happening transparently. This way you never have to worry about catching a WebException for the 400 or the 401 and the only thing you've wasted is a quick call to a no-op method on the web service -- much better than catching the 400 and sending the big request back to the server.

Posted by JoshC at July 27, 2003 03:40 PM
Trackbacks
TrackBack URL for this entry:
http://www.joshchristie.com/weblog/mt/mt-tb.cgi/16

Listed below are links to weblogs that reference '.NET bug for large web service requests' from Josh Christie's Weblog.
Comments
Post a comment









Remember personal info?