Skip to content

How to Deserialize Delta<T> from JSON using oDataMediaTypeFormatter with Entity Framework Code First

February 6, 2013

Today I was struggling trying to work out how I can make use of the oDataMediaTypeFormatter in ASP.Net Web API when you only have a code first model to work with. For the impatient, scroll to the bottom for the quick solution!

The Problem

I’d been reading various articles about oData, Particularly the following:

spc

What I was actually trying to do was to implement partial updates to resources using the PATCH verb, and it all seemed really simple on paper. However when it came down to it, there were several problems:

  • You can’t use the [FromData] attribute with a Delta<T> parameter as this throws an exception
  • JsonMediaTypeFormatter doesn’t seem to be able to deserialise to Delta<T>, contrary to what the TechBrijj article suggests.
  • spc

Given the above, I tried to follow the instructions for ‘Doing more oData’ from Alex J’s article hoping to make use of the oDataMediaTypeFormatter. From the article:

// Create the OData formatter and give it the model 
ODataMediaTypeFormatter odataFormatter = new ODataMediaTypeFormatter(model);
spc

There were more issues though:

At this point I did what any upstanding developer would do, I swore loudly and went to lunch.

The Solution

Isn’t it annoying when things turn out to be so simple? Poring over the oData package source I found out it’s actually very easy to instantiate the media type formatter. Additionally, it was also a one liner to interpret the code first model (see below)

For additional reasons not explained here, I chose to wrap everything up in another custom MediaTypeFormatter, but anywhere you have a reference to an HttpContent object would work fine too.

public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
    var serialiser = new JsonSerializer();

    var builder = new ODataConventionModelBuilder();
    
    // This line will allow you to interpret all the metadata from your code first model
    builder.EntitySet<EfContext>("EfContext");

    var model = builder.GetEdmModel();
    var odataFormatters = ODataMediaTypeFormatters.Create(model);
    var delta = content.ReadAsAsync(type, odataFormatters).Result; 

    var tcs = new TaskCompletionSource<object>(); 
    tcs.SetResult(delta); 
    return tcs.Task; 
}
spc

So there we go. Hopefully someone will find this useful and not lose a morning because of it! Thanks to @filip_woj for his assistance on this issue.

spc
spc

Pete

From → OData, REST, Web API

One Comment
  1. hi roysvork, is it work in odata v4?

Leave a comment