WCF-WebHttp and custom JSON error messages
I’m currently working on a solution that exposes a BizTalk Orchestration as a RESTful webservice using WCF-WebHttp. Upon successful processing of the message, the service returns binary data for the client to download. However, if the processing fails, I wanted the service to return application/json data with an error message that would be suitable for consumers – I did not want Stack Traces or other internal details to be provided that could potentially be used by malicious consumers. Further, I wanted to ensure this information was sent in the same session.
To resolve these issues, I created a custom WCF Behavior with three classes.
The class which does most of the work, SanitizedJsonFaultHandler, implements IErrorHandler, and contains a subclass JsonErrorBodyWriter to help with JSON serialization. In the ProvideFault override, I parse the exception message into an XDocument. One of the fields in that document is the HTTP Status Code I wish to use for that message (400 if the validation of the file failed, 500 if an internal exception occurred); this field gets removed, as it would be redundant to include it in the message body. I then set the fault message using the JsonErrorBodyWriter class to serialize the XML message to a JSON message. The message has only a root node and string value child nodes.
Two other classes help make this behavior available to the BizTalk adapter. One implements IEndpointBehavior, adding my custom error handler to the endpointDispatcher:
And another overrides BehaviorExtensionElement so that this behavior will be visible to the system:
Finally, I added the following line to my machine.config files (32 and 64 bit; replace FULLNAMESPACE with your namespace and FULLY_QUALIFIED_NAME with the FQN of the DLL you create and GAC. This information can be found by running the command ‘
gacutil /l | find "WCFBehaviors"‘).
<add name="SanitizedJsonFault" type="FULLNAMESPACE.WCFBehaviors.SanitizedJsonFaultBehaviorElement, FULLY_QUALIFIED_NAME"/>
With this done, I restarted IIS and BizTalk. Then I was able to add the endpoint behavior by right clicking on EndpointBehavior:
Now, my orchestration can log the sensitive information for later review (or send it to an administrator directly), and the fault message is sent back to the client like so: