WCF Bad Request
I’ve just identified a horrible bug in WCF for the .NET Framework 3.5.
A caught exception in a WebInvoke operation will cause WCF to return an HTTP 400 Bad Request status code to the client. Any caught exception. Every time. Regardless of whatever error code you might want to send back.
I found the error by mistake. I’d used “BadGateway” instead of “BadRequest” in my code. If it weren’t for other odd WCF behavior, I wouldn’t have noticed that my status code was being ignored.
Consider the following example:
-
// Read the Xml into our object and save.
-
try
-
{
-
// The following line triggered the error.
-
obj.ReadXml(reader);
-
obj.Save();
-
// Set HTTP Cache Options and MIME Type.
-
Utilities.SetCaching(WebOperationContext.Current, obj.DateModified, 60);
-
Utilities.SetMimeType(Format.Xml);
-
return Utilities.GetXmlStream(obj);
-
}
-
catch (Exception e)
-
{
-
// Was it a schema validation error? If so, provide detail.
-
if (!string.IsNullOrEmpty(_XmlValidationErrors))
-
{
-
// I slipped here, using BadGateway 502 instead of Bad Request 400.
-
// But WCF doesn't care. If you enter the catch block it's _always_ 400.
-
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.BadGateway;
-
WebOperationContext.Current.OutgoingResponse.StatusDescription = _XmlValidationErrors;
-
WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = false;
-
return null;
-
}
-
}
If no error occurs, WCF will return the status code you specify. A try/finally block will work just fine; WCF returns whatever status code you specify. Enter a catch block, though, and it’s nothing but 400 Bad Request.
Hey, if there’s an error, it must be the client’s fault, right?
Related Posts
- REST: How to respond to an HTTP POST
- WCF Instance Context
- Using WCF for REST, Part 2
- Handling COM Error Codes
- Looking for an IIS Alternative
Grrr..
It seems like it’s “by design” in the webhttp binding.
Apparently you’re supposed to override the webhttpbinding and implement your own custom error handler.
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2248288&SiteID=1
As if we needed more proof that the webhttp binding was an afterthought to the ultra soapy WCF anyway… * sigh *
Nice — I like how they assume that the server getting an unhandled exception is actually the fault of the client.
Most other environments manage to make do with 500 errors for that sort of thing
[...] finally figured out the source of my bad request problem. Apparently the Windows Communication Foundation deals with exceptions differently [...]
Not sure if this helps your particular case, but this guy found that changing the InstanceContextMode made a similar problem go away…
http://underground.infovark.com/2008/05/21/wcf-instance-context/
That’s funny, @trcull. You just highlighted a link to another post of mine! I found the answer to the problem described here, in April 2008, one month later, in May 2008.
A commenter on that post confirmed that it seemed to be a glitch related to InstanceContextMode.