Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net MVC : Sending JSON to Controller

I want to be able to send JSON as opposed to the standard QueryStrings when making a post to my controllers in ASP.Net MVC. I have the Front-End stuff working fine (building and then submitting my JSON objects).

The problem is on the controller side where the default ModelBinders that ship with the MVC framework do not support this.

I have seen a combination of ways around this, one of them is to apply a filter which takes the object as a parameter, uses a JSON library to de-serialise it, and adds that to the action parameters. This is not ideal.

The other, better, way is to use a custom Model Binder. All the ones I have seen though presume you will have only one model and that will be a class rather than a variable. If you have multiple ones it breaks down.

Has anyone else encountered this? One idea I had was if I could simply override how MVC deals with the FormCollection and intercept there, adding the values to the collection myself and hoping MVC can do the rest in it's normal fashion. Does anyone know if that is possible?

The key issue, I think, is that my problem is not with binding because my view models are no different to how they where before. The problem is getting the values from the JSON Post.

If I am correct MVC get's the values from the QueryString and puts it into the form collection which is then used for ModelBinding. So shouldn't the correct method be to change the way the FormCollection gets assigned?

Example of an action:

public ActionResult MyFirstAction(Int32 ID, PersonObject Person, ClassObject ClassDetails)
{
//etc
}

The normal binding works, JSON doesn't and all the example of Model Binders will not work either. My best solution so far is to convert the object to a dictionary and loop though each param and match it up. Doesn't seem ideal.

like image 955
Damien Avatar asked Jan 26 '10 16:01

Damien


People also ask

How pass JSON object in post request in MVC?

Make sure you specify POST type, as ajax method uses GET method by default. MVC Controller: Decorate the Action method with HttpPost verb. This action method will only handle http post request from browser. Ajax submission from the browser will be automatically deserialized to FormData c# class as a poco.

Why we use JsonResult in MVC?

JsonResult is an ActionResult type in MVC. It helps to send the content in JavaScript Object Notation (JSON) format.

Which class will you use for sending the result back in JSON format in MVC?

For sending back the result in JSON format in any MVC application, you have to implement the “JSONRESULT” class in your application.


1 Answers

I use a custom model binder for json like this:

public class JsonModelBinder<T> : IModelBinder {
    private string key;

    public JsonModelBinder(string requestKey) {
        this.key = requestKey;
    }

    public object BindModel(ControllerContext controllerContext, ...) {
        var json = controllerContext.HttpContext.Request[key];
        return new JsonSerializer().Deserialize<T>(json);
    }
}

And then wire it up in Global.asax.cs like this:

ModelBinders.Binders.Add(
    typeof(Product),
    new JsonModelBinder<Product>("ProductJson"));

You can read more about this here: Inheritance is Evil: The Epic Fail of the DataAnnotationsModelBinder

EDIT

The JsonModelBinder should be used on the controller action parameter typed as Product only. The Int32 and ClassObject should fall back to the DefaultModelBinder. Are you experiencing a different result?

like image 54
Mike Valenty Avatar answered Sep 23 '22 01:09

Mike Valenty