I just attended the Microsoft PDC in LA. One of the many excellent sessions was a pre-conference on WCF, part of which was presented by Ron Jacobs. Ron did a fantastic job of explaining WCF REST Services and the WCF REST Starter Kit.
One of the examples he showed from the WCF REST Starter kit was an example where the response type (JSON or XML) is dynamically set based on the HTTP request's requested content type in the "Accepts" HTTP Header.
That example works by switching between two different operation implementations (methods).
I liked the idea of using the requested content type to automatically return JSON or XML depending on the requested content type, but I wasn't so keen on having to implement two methods.
I thought I'd try to get a similar thing working but using a single operation implementation which is called no matter whether or JSON or XML are requested.
The DynamicResponseType attribute
This is how it works. You decorate your method with an additional DynamicResponseType attribute which I have defined:
An example client
Then when the client requests a specific type (XML or JSON), it is served automatically.
The first button says it wants JSON, and the second XML. This is done by setting the "Accept" request header:
This is the form that gets displayed initially:
When you click on the first button we request JSON from the WCF Service operation:
When you click on the second button we request XML from the same WCF Service operation:
How it works.
I've created my own WCF ServiceHostFactory which I wire up in the SVC file:
In my ServiceHostFactory2Ex class I ensure that my own WebServiceHost class gets created.
Then in my own WebServiceHost I ensure that my own WebHttpBehavior replaces the standard one.
Next in my own WebHttpBehavior I override the GetReplyDispatchFormatter method and return my own IDispatchMessageFormatter.
In my own IDispatchMessageFormatter I implement the SerializeReply method and then use a JSON formatter or XML formatter depending on the "Accepts" HTTP request header which I pick up from the OperationContext.Current.RequestContext.RequestMessage.
The full source is available for download here http://damianblog.com/WCFDynamicResponseDemo.zip.
Rob Jacobs blogs at http://blogs.msdn.com/rjacobs/