I have a Wcf (ajax enabled) service, that accepts a object for the method call. My Wcf method looks like this;
[OperationContract]
[XmlSerializerFormat]
[WebInvoke(Method = "POST", UriTemplate = "/XML/GetTypes", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml)]
XElement XMLGetTypes(TypeRequest TypeRequest)
{
return Utilities.Convert.ObjectToXElement(TypeRequest.Execute(TypeRequest));
}
The 'TypeRequest' object is as follows;
public class
{
public int Id {get;set;}
public string Name {get; set;}
}
The problem I'm having is that if I call the method with invalid data like in the request object like;
<TypeRequest>
<Id>abc</Id>
<Name>Joe King</Name>
</TypeRequest>
As you can see the Id should be a integer, however it is being passed as a string. This causes a Bad Request 400 response from the Wcf service.
Ideally I'd like to handle the error, and return a suitable response. For example I'd like to return either a JSON or XML response containing the error information.
Is this possible ?
IIS allows you to create error handlers overall in the pipeline. How you handle the code and what you return is up to you, though I would be careful, as this handles all the errors for an IIS application.
public class ErrorHttpHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
if (context.Request.QueryString.Count == 0)
return;
string strStatusCode = context.Request.QueryString[0].Split(';').FirstOrDefault() ?? "500";
int statusCode = 500;
int.TryParse(strStatusCode, out statusCode);
string message = "Unhandled server error.";
switch (statusCode)
{
case 400:
message = "Bad request.";
break;
case 404:
message = "Item not found.";
break;
}
context.Response.StatusCode = statusCode;
context.Response.Write(string.Format("<Error><Message>{0}</Message></Error>", message));
}
}
and in your web.config, add this code for the handler to be called:
<system.webServer>
<httpErrors errorMode="Custom">
<clear/>
<error statusCode="404" path="/application/ErrorHandler" responseMode="ExecuteURL"/>
<error statusCode="400" path="/application/ErrorHandler" responseMode="ExecuteURL"/>
</httpErrors>
<handlers>
<add name="ErrorHandler" path="ErrorHandler" verb="*" type="Your Application.ErrorHttpHandler, FrameworkAssembly"/>
</handlers>
</system.webServer>
All of this was culled from this site.
You can check your parameter using parameter inspector, which will allow you to throw fault exception with the message you need. Also you can provide your client (if it's .net client) with you Parameter inspector attribute. As a result the message will not be send till it pass validation, which can save you traffic. Here is a link:
WCF Parameter Validation with Interceptor
And in case your client send you a wrong message. You have to use message inspector:
MSDN, Logging all WCF messages
Here is even better example:
http://msdn.microsoft.com/en-us/library/ff647820.aspx
You have to put more attention for methods AfterReceiveRequest. Please notice that it's required to create a buffered copy of the message, then work with one copy of a message, and return another one.
it is possible to do this but you may need to do it a little differently, the easiest way may be to alter your incoming Type request as follows
public IncomingClass
{
public string Id {get;set;}
public string Name {get; set;}
}
this will mean that the incoming data is valid, and you won't get the error 400,
you can then validate this using
int myId = incomingClass.Id as int;
if (myId == null)
{
//put suitable error handling here
}
or perhaps better still stick the whole function in a try catch loop, and handle the error that way. I think you will find the error is happening before you are entering your function. your WCF Service is expecting xml that can be translated to the type of Object "TypeRequest" but your xml is invalid.
Hope that helps
I think you would need some method interceptors and write the expected logic in there.
Here's a good resource on that http://msdn.microsoft.com/en-us/magazine/cc163302.aspx