Suppose I want to return a list of users in JSON or CSV format depending on a query parameter.
MyService.svc/users?format=json returns JSON
MyService.svc/users?format=csv returns CSV
The question is: how do I implement it with WCF (leaving aside the discussion on whether it’s a good idea)?
The answer: the multi-format method must have return type Stream. The programmer is fully responsible for formatting the response body in all cases, including setting Content-Type.
[ServiceContract]
public interface ITestService
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "users?format={format}")]
Stream GetUsers(string format);
}
Solution attempts that did not work
1. You cannot have two methods that differ only on query parameters.
[ServiceContract]
public interface ITestService // Does not work as expected
{
[WebInvoke(Method = "GET", UriTemplate = "users?format=json", ResponseFormat = WebMessageFormat.Json)]
List GetUsers();
[WebInvoke(Method = "GET", UriTemplate = "users?format=csv")]
Stream GetUsers();
}
This throws an exception at runtime saying one cannot have two methods whose URI templates differ only by query parameters.
2. You cannot have a method that returns object. I expected WCF to turn off response formatting when dynamic response type is Stream. This turned out to be not the case. WCF turns off response formatting only when the method’s static return type is Stream. See
my question on StackOverflow.
Things to pay attention to
1. If you create a MemoryStream and write into it, make sure to reset the pointer to the beginning. If you don’t, the response body will be empty.
2. Don’t forget to set Content-Type and (optionally) Content-Disposition.
3. JSON must be serialized by hand.
4. Don’t forget to properly handle case of bad request parameters.
Code:
https://github.com/ikriv/wcf-rest-multiformat
Originally posted on
www.ikriv.com/blog/.