This is arguably one of the more irritating things in WCF, but as it turns out for good reason. WCF is meant to expose services 'universally' of their endpoint i.e. it shouldn't matter how you connect to the server, the service is independent of the underlying protocol. Therefore, returning HTTP errors from WCF service, well, doesn't work out of the box. It is therefore not surprising that when we attempted to return HTTP errors directly from the service, .NET was converting every error into HTTP 500 which is not what we were after.
The proper way around this problem is to abstract from HTTP layer and provide your custom errors which then would be converted to appropriate error format (e.g. HTTP). This is done by implementing IErrorHandler
. I don't really want to go into details explaining how IErrorHandler works in this article since there are plenty of other articles that will do it more accurately than I can. The key point is that: in order to return a HTTP Error (like 401) we need to use fault provider:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault) { //Just checking if the Exception is a HttpException if (error is HttpException) { //Type casting HttpException s = (HttpException)error; //Extracting the Error Code HttpStatusCode status = (HttpStatusCode)s.GetHttpCode(); //creating a message to be sent to the client fault = Message.CreateMessage(version, "", error.Message); //We can add properties with the error code and message associated with it. fault.Properties.Add(HttpResponseMessageProperty.Name, new HttpResponseMessageProperty { StatusCode = status, StatusDescription = s.Message }); } } |