Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible for an asp.net MVC "Action Method" to receive JSON without declaring its specific type on the parameter? If so, how?

So, it pretty much is all in the title. Basically, I want to send a JSON through JQuery from client to asp.net MVC. I'm wondering if it's possible for it to receive (but not necessarily parse) any JSON I want to send from JQuery Ajax call, regardless of it's type.. without me having a concrete type/model representation of it. (basically like a dynamic type?)

Doing this the regular way (with me declaring the passing argument as type Object) just brings about nulls, which was what I expected.

Basically, I want to do some kind of "reflection for JSON" type stuff when I receive it, and be able to get it's properties through some kind of foreach loop and etc.

Thanks in advance. Any help would be great!

like image 771
Jan Carlo Viray Avatar asked Dec 31 '11 08:12

Jan Carlo Viray


1 Answers

You could use an IDictionary<string, object> as action argument. Just write a custom model binder that will parse a JSON request into it:

public class DictionaryModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
        {
            return null;
        }

        controllerContext.HttpContext.Request.InputStream.Position = 0;
        using (var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream))
        {
            var json = reader.ReadToEnd();
            if (string.IsNullOrEmpty(json))
            {
                return null;
            }
            return new JavaScriptSerializer().DeserializeObject(json);
        }
    }
}

which will be registered in Application_Start:

ModelBinders.Binders.Add(typeof(IDictionary<string, object>), new DictionaryModelBinder());

then you could have the following controller action:

[HttpPost]
public ActionResult Foo(IDictionary<string, object> model)
{
    return Json(model);
}

to which you can throw anything:

var model = {
    foo: {
        bar: [ 1, 2, 3 ],
        baz: 'some baz value'
    }
};

$.ajax({
    url: '@Url.Action("foo")',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(model),
    success: function (result) {
        // TODO: process the results from the server
    }
});
like image 111
Darin Dimitrov Avatar answered Oct 15 '22 22:10

Darin Dimitrov