Monday, August 10, 2009

MVC JSON Model Binder Attribute

Here it is folks: the Ultimate Ultimate* ASP.NET MVC JSON Model Binder!

Moving complex data structures from client to server used to be difficult, but not anymore! Just add the JsonBinder attribute to your action parameters, and this Custom ModelBinder will automatically detect the type and parameter name, and deserialize your complex JSON object to the data structure of your choice.

No configuration required, it works every time, it's PFM!**

* Yes, I said Ultimate twice.
** Pure Friendly Magic

JsonBinderAttribute

public class JsonBinderAttribute : CustomModelBinderAttribute
{
    public override IModelBinder GetBinder()
    {
        return new JsonModelBinder();
    }
 
    public class JsonModelBinder : IModelBinder
    {
        public object BindModel(
            ControllerContext controllerContext, 
            ModelBindingContext bindingContext)
        {
            try
            {
                var json = controllerContext.HttpContext.Request
                           .Params[bindingContext.ModelName];
 
                if (String.IsNullOrWhitespace(json))
                    return null;
 
                // Swap this out with whichever Json deserializer you prefer.
                return Newtonsoft.Json.JsonConvert
                       .DeserializeObject(json, bindingContext.ModelType);
            }
            catch
            {
                return null;
            }
        }
    }
}

Controller Action

public class PersonController : Controller
{
    // Note: The JsonBinder attribute has been added to the person parameter.
    [HttpPost]
    public ActionResult Update([JsonBinder]Person person)
    {
        // Both the person and its internal pet object have been populated!
        ViewData["PetName"] = person.Pet.Name;
        return View();
    }
}

Sample Models

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    // Note: This property is not a primitive!
    public DomesticAnimal Pet { get; set; }
}
 
public class DomesticAnimal
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Species { get; set; }
}

jQuery Method

function sendToServer() {
    var person = {
        Name : 'Tom',
        Age : 27,
        Pet : {
            Name : 'Taboo',
            Age : 2,
            Species : 'Shiba Inu'
        }
    };
 
    // {"Name":"Tom","Age":27,Pet:{"Name":"Taboo",Age:2,Species:"Shiba Inu"}}
    var personJson = JSON.stringify(person);
 
    $.ajax({
        url: 'Person/Update', 
        type: 'POST',
        data: { 
            person: personJson 
        }
    });
}
Shout it

Enjoy,
Tom

4 comments:

  1. Thanks Tom, this post (even though it is a couple of years old) really helped me out!

    ReplyDelete
  2. I've spent hours trying to make this work in MVC 4. I have a breakpoint in the controller, but all the fields in person are zero or null. Any suggestions on how to troubleshoot this? More puzzling, and possibly unrelated, when I use curl to POST, the person object itself is null.

    ReplyDelete
  3. We work hard to ensure that you get the suitability you need. If you have any questions about your dissertation or want to know how to hire an expert to do your dissertation for you, ask them, and we will answer. We have a team ready and waiting to answer all your questions regarding our Dissertation Help Near Me UK.

    ReplyDelete
  4. The company works with local US English order essay native speakers, as well as consistent ESL essay helpers. Looking for an essay writing service online that is legit, this site would be one of your top picks.

    ReplyDelete

Real Time Web Analytics