Alexander Beletsky's development blog

My profession is engineering

JSON Model Binding to IDictionary<> is Broken

Yesterday, I’ve been creating small web service based on existing ASP.NET MVC infrastructure. The task was really simple. Web service itself should be just a proxy for existing internal API. The API method takes a Dictionary that contains some fields. So, I’ve created a data model like that.

public class Notification
{
 public int Id { get; set; }
 public string Recipient { get; set; }
 public IDictionary<string, string> Fields { get; set; }
}
    

and simple HttpPost handler, like

[HttpPost]
public ActionResult Send(string token, Notification notification)
{
    // ...
}
    

the payload posted to method is:

{"id":32,"recipient":"a@a.com","fields": { "EMAIL": "a@a.com"} }

    

I’ve tried to test the method, but the Fields property of model was always null. First I thought I got a problem somewhere in JSON payload, but after sometime I saw that everything is correct.

Google showed I’m not alone, so the issue been raised on SO. Darin Dimitrov responded that this is a bug of JsonValueProviderFactory. In the same time, some comments below contained the link for a bug reported, that was already stated as Fixed.

I forgot to mention that I did that stuff on ASP.NET MVC 2. I decided to try that on ASP.NET MVC 3, since I got the sources and if it works I can try to backport the fix into our MVC 2 infrastructure.

With my great disappointment it fails in exactly same way for ASP.NET MVC 3. That’s not funny anymore. I blamed JavaScriptSerializer, JSON serializer that used inside the JsonValueProviderFactory that it simply not able to handle Dictionaries right. I knew that ASP.NET Web API is using Newtonsoft JSON.NET framework, which is really powerful for serialization/deserialization of JSON.

So, I run VS 2011 and create test ApiController that receives the model with IDictionary inside. What do you think happen? Ok, the model is no longer null, but it contains Dictionary with count of elements equals to zero. Fail.

public void Post(Notification notification)
{
    // ...
}
    

I re-raised issue again, now on ASP.NET Web Stack site on Codeplex. I also tried to quickly write the unit test that show the existence of problem, but it’s not that easy to do that, so it requires some time. Hope I can do that later.