
{"id":1841,"date":"2015-12-31T03:27:09","date_gmt":"2015-12-31T08:27:09","guid":{"rendered":"http:\/\/www.ikriv.com\/blog\/?p=1841"},"modified":"2015-12-31T03:27:09","modified_gmt":"2015-12-31T08:27:09","slug":"wcf-restful-service-returning-data-in-different-formats-depending-on-request-parameter","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=1841","title":{"rendered":"WCF Restful service: returning data in different formats depending on request parameter"},"content":{"rendered":"<p>Suppose I want to return a list of users in JSON or CSV format depending on a query parameter.<\/p>\n<p><code>MyService.svc\/users?format=json<\/code> returns JSON<br \/>\n<code>MyService.svc\/users?format=csv<\/code> returns CSV<\/p>\n<p><b>The question is:<\/b> how do I implement it with WCF (leaving aside the discussion on whether it&#8217;s a good idea)?<\/p>\n<p><b>The answer:<\/b> the multi-format method must have return type <code>Stream<\/code>. The programmer is fully responsible for formatting the response body in all cases, including setting Content-Type.<\/p>\n<p><code><\/p>\n<pre>\n    [ServiceContract]\n    public interface ITestService\n    {\n\n        [OperationContract]\n        [WebInvoke(Method = \"GET\", UriTemplate = \"users?format={format}\")]\n        Stream GetUsers(string format);\n    }<\/pre>\n<p><\/code><\/p>\n<h2>Solution attempts that did not work<\/h2>\n<p>1. You cannot have two methods that differ only on query parameters.<\/p>\n<p><code><\/p>\n<pre>\n    [ServiceContract]\n    public interface ITestService \/\/ <font color=\"red\">Does not work as expected<\/font>\n    {\n\n        [WebInvoke(Method = \"GET\", UriTemplate = \"users?format=json\", ResponseFormat = WebMessageFormat.Json)]\n        List<userInfo> GetUsers();\n\n        [WebInvoke(Method = \"GET\", UriTemplate = \"users?format=csv\")]\n        Stream GetUsers();\n    }<\/pre>\n<p><\/code><\/p>\n<p>This throws an exception at runtime saying one cannot have two methods whose URI templates differ only by query parameters.<\/p>\n<p>2. You cannot have a method that returns <code>object<\/code>. I expected WCF to turn off response formatting when <b>dynamic<\/b> response type is <code>Stream<\/code>. This turned out to be not the case. WCF turns off response formatting only when the method&#8217;s <b>static<\/b> return type is <code>Stream<\/code>. See <a href=\"http:\/\/stackoverflow.com\/questions\/34499917\/how-to-return-csv-or-json-from-a-restful-wcf-call-depending-on-a-parameter\/34507514#34507514\">my question on StackOverflow<\/a>.<\/p>\n<h2>Things to pay attention to<\/h2>\n<p>1. If you create a <code>MemoryStream<\/code> and write into it, make sure to reset the pointer to the beginning. If you don&#8217;t, the response body will be empty.<\/p>\n<p>2. Don&#8217;t forget to set <code>Content-Type<\/code> and (optionally) <code>Content-Disposition<\/code>.<\/p>\n<p>3. JSON must be serialized by hand.<\/p>\n<p>4. Don&#8217;t forget to properly handle case of bad request parameters.<\/p>\n<p>Code: <a href=\"https:\/\/github.com\/ikriv\/wcf-rest-multiformat\">https:\/\/github.com\/ikriv\/wcf-rest-multiformat<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 <a href=\"https:\/\/ikriv.com\/blog\/?p=1841\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[15],"tags":[],"class_list":["entry","author-ikriv","post-1841","post","type-post","status-publish","format-standard","category-webdev"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1841","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1841"}],"version-history":[{"count":0,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1841\/revisions"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1841"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1841"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1841"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}