I’ve been making use of the JsonValueProviderFactory a lot lately. The JsonValueProviderFactory was released as part of MVC 3 and is a really easy way to introduce Json into your web application. In fact all MVC 3 websites support posting Json off the bat with no code changes. Phil Haack wrote an excellent blog post introducing the JsonValueProviderFactory.
One limitation I’ve found with the current JsonValueProviderFactory is when you have a property in your model that is a dynamic type. Unfortunately the JsonValueProviderFactory is unable to bind deserialized Json to a dynamic property. Example below:
My solution JsonDotNetValueProviderFactory
The current JsonValueProviderFactory implements the ValueProviderFactory abstract class and overrides the GetValueProvider method. The GetValueProvider method needs to return a IValueProvider. The JsonValueProviderFactory does this by returning a DictionaryValueProvider<object> which implements IValueProvider. The DictionaryValueProvider constructor takes a IDictionary<string, object> which populates the ValueProvider.
It’s the DictionaryValueProvider constructor taking IDictionary<string, object> which makes things easy for us. Why? The ExpandoObject implements IDictionary<string, object> all we need to do is deserialize Json to an ExpandoObject and we should have a solution. Fortunately the awesome Json.Net library has a ExpandoObjectConverter that will deserialize Json to an ExpandoObject. Below is the finished JsonDotNetValueProviderFactory using the ExpandoObjectConverter (I also reduced the code current JsonValueProviderFactory 73 lines JsonDotNetValueProviderFactory 27 lines):
Replacing the JsonValueProviderFactory
This is done in the Application_Start() method in Global.asax by removing the JsonValueProviderFactory from ValueProviderFactories.Factories and adding the JsonDotNetValueProviderFactory. Example below:
If you run into the same limitation with the JsonValueProvider as I did I hope you find this post useful. I’ve also written a small test harness MVC project that shows a model with a dynamic property not binding using the JsonValueProviderFactory and binding correctly using my JsonDotNetValueProviderFactory. The project also contains unit tests for the JsonDotNetValueProviderFactory. The test harness project is on GitHub https://github.com/DalSoft/JsonDotNetValueProviderFactory and can also be downloaded as a zip file.