Vishful thinking…

Customizing the response serialization in WCF REST services

Posted in Uncategorized by viswaug on May 22, 2008

I am in the process of creating WCF REST services for one of the projects I am currently working on. I love the REST programming model introduced in .NET 3.5 and how simple it makes things. But I also think that the REST programming model in .NET 3.5 is not as good as it can be and there will be more “RESTful goodness” coming in the later service packs and releases. The DataContract serialization has already been improved upon in SP1. DataContract has made the serialization in .NET better in a lot of ways but I like the opt-in mechanism in DataContract serialization instead of the opt-out mechanism like in the XmlSerializer.

The extensibility of WCF is amazing and sometimes overwhelming. There are multiple ways by which you can customize the request and response serialization in WCF. The XmlSerializer helps you take complete control over the XML format in which the response is serialized. And there are a lot of documentation on the web that show you how it can be done. But I was looking to return GeoJSON generated by the GeoJSON.NET library from the WCF REST service. The GeoJSON.NET library uses the NetTopologySuite(NTS) library to create GeoJSON from. Even though, the DataContract serialization is highly customizable, I had two problems, I did not have control over the NTS geometry and feature types(to decorate them with the DataContract attributes) and also the flexibility of the DataContract serializer might still not be good enough to generate the GeoJSON format required from the NTS types. Generating GeoJSON string from the GeoJSON.NET library and returning the string from the WCF REST service still had a problem. The GeoJSON output was getting wrapped in quotes and that is not a good thing. After, spending some time evaluating the options available to customize the JSON response from the WCF REST, I found that there are a lot of options for customizing the XML serialization and not as much for JSON serialization. Finally, I settled on returning a Stream from the WCF REST service which will give me complete control over the response from the WCF REST service. When returning a Stream, WCF stays clear of the response and doesn’t mess with the response by applying any default serialization. This way I can return exactly what I want to from the REST service.

Here is how to return the string response in a “raw” stream format.

public Stream GetJSON()

        {

            Byte[] data = Encoding.UTF8.GetBytes(“{hey: ‘there’, hello: ‘world’}”);

            MemoryStream ms = new MemoryStream(data);

            return ms;

        }

or

public Stream GetJSON()

        {

            WebOperationContext.Current.OutgoingResponse.ContentType = “text/json”;

            MemoryStream ms = new MemoryStream();

            StreamWriter sw = new StreamWriter(ms);

            sw.Write(“{hey: ‘there’, hello: ‘world’}”);

            sw.Flush();

            ms.Position = 0;

            return ms;

        }

Make sure to set to position on the stream to ZERO before returning. If you don’t, the response is always going to be empty. That finally dawned on me after numerous hours of my banging my head against the wall.

Also, setting the ‘ContentType” on the outgoing response is not a requirement but it is a good RESTful practice. Here is a good look-up for setting the content type in case you are returning other kinds of data.

4 Responses

Subscribe to comments with RSS.

  1. Vikas Manghani said, on July 24, 2008 at 6:33 am

    Hi
    Is it possible to prompt the File Download Dialog box on the browser using the same method i.e. returning a Stream as the output parameter?
    Actually, I have tried this but it doesnt prompt the File Download Dialog box. I have set the Content-Disposition header to attachment; filename=FILENAME, Content-Type header to application/octet-stream on the WebOperationContext.OutgoingResponse. Still it doesnt work
    Can you tell me how to go about doing this?
    Thanks in advance
    Vikas Manghani

  2. n4a4 said, on June 14, 2011 at 5:12 pm

    great stuff! thanks buddy

  3. ShoomKloom said, on April 20, 2012 at 7:37 pm

    Of course!
    Set the stream to 0 !!
    You saved me man, thanks a million!

  4. vudq said, on May 7, 2012 at 9:42 am

    great solution!
    But it doesn’t work when i get JSONP cross-domain. There aren’t callback function in return content.
    Do you have solution for this case?
    Thanks,

    Vu


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: