Ok, so I have a pretty basic web page that displays a paginated grid of a collection of my business objects. This grid gets displayed when I perform a simple string search on let’s say my entity name. Of course, everyone hates dealing with full postbacks, so I want to perform this search via javascript, or more specifically via an AJAX call.
Using the typical form post method common in many ASP.NET MVC applications doesn’t really work in my scenario because I’m not mapping all the necessary fields upon landing on my page.
I know I want to use JQuery’s AJAX capabilities to post my search string information, but I couldn’t figure out a way to do it without passing in an “ugly” set of query strings and having to accept 3 parameters in my Controller Action method.
Basically I didn’t want to have to have something like this:
(oh by the way, going forward in this post, ignore my custom “NoCache” attribute in any of my code snippets. It’s not related to this post, but I use it all the time now because of the automatic post caching feature in IE).
Ok, so if you look at the method signature, it really doesn’t look THAT bad right? Well it’s not bad, but the problem is that I’m sure I’ll have other pages that need to perform AJAX calls that will pass in other sets of parameters. I want one to have a nice POCO that I can work with that gets “automatically” mapped for me.
I want something like this:
Where the definition of EntitySearchOutput is:
So, making use of Google’s jquery.json library, and javascript objects, I’m able to write the following javascript code that calls my “SearchEntities” controller action.
So what this actually does is builds out my “searchData” javascript object and then runs through the “$.toJSON” function to convert the javascript object to a JSON object called “searchDataJSON”. This in turn gets passed to my “SearchEntities” method as a JSON string. As a side note, line 12 is necessary for IE so that the JSON string gets created in a way that can be de-serialized by .NETs JavascriptSerializer as you’ll see soon.
So how does the application know to convert what I passed in javascript to my EntitySearchOutput class? That’s where an IModelBinder implementation comes into play.
As you can see, this JsonModelBinder class does not say anything about EntitySearchOutput. As a matter of fact, it is a generic class which means, yes, it can be used for any class provided it is Javascript serializable. So you can do this with deep complex arrays. The one method you must implement is called “BindModel” which gives you a reference to the HttpContext. The json String exists in the HttpContext.Request parameter. Simple use the JavaScriptSerializer framework class and deserialize to the generic type T and return the results.
The final piece of this to tie in the model binder comes in the Global.asax.cs
The “SetupModelBinders” method makes a call that tells the MVC Framework to always using the JsonModelBinder class to create an EntitySearchOutput object when it is specified as a parameter of a controller action.
Now the controller action will work as expected:
The final part of this method returns back JSON to our javascript AJAX call, it JSON serializes an “EntitySearchResultsInput” class defined here:
So that the following “jsonResult” object is populated on line 17 below:
You can access properties on “jsonResult” simply by typing in: jsonResult.TotalResults or jsonResult.Entities[0].Name
So that’s an example of one implementation of IModelBinder. You might find other things you want to do with other types of ModelBinders. I actually created another one for a specific scenario I had with arrays of integers. Here is that ModelBinder. I’ll leave it to you to see how you might use it.
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.