Passing dynamic json object to C# MVC controller

Solution 1:

Presumably the action that accepts input is only used for this particular purpose so you could just use the FormCollection object and then all your json properties of your object will be added to the string collection.

[HttpPost]
public JsonResult JsonAction(FormCollection collection)
{
    string id = collection["id"];
    return this.Json(null);
}

Solution 2:

You can submit JSON and parse it as dynamic if you use a wrapper like so:

JS:

var data = // Build an object, or null, or whatever you're sending back to the server here
var wrapper = { d: data }; // Wrap the object to work around MVC ModelBinder

C#, InputModel:

/// <summary>
/// The JsonDynamicValueProvider supports dynamic for all properties but not the
/// root InputModel.
/// 
/// Work around this with a dummy wrapper we can reuse across methods.
/// </summary>
public class JsonDynamicWrapper
{
    /// <summary>
    /// Dynamic json obj will be in d.
    /// 
    /// Send to server like:
    /// 
    /// { d: data }
    /// </summary>
    public dynamic d { get; set; }
}

C#, Controller action:

public JsonResult Edit(JsonDynamicWrapper json)
{
    dynamic data = json.d; // Get the actual data out of the object

    // Do something with it

    return Json(null);
}

Annoying to add the wrapper on the JS side, but simple and clean if you can get past it.

Update

You must also switch over to Json.Net as the default JSON parser in order for this to work; in MVC4 for whatever reason they've replaced nearly everything with Json.Net except Controller serialization and deserialization.

It's not very difficult - follow this article: http://www.dalsoft.co.uk/blog/index.php/2012/01/10/asp-net-mvc-3-improved-jsonvalueproviderfactory-using-json-net/

Solution 3:

Another solution is to use a dynamic type in your model. I've written a blog post about how to bind to dynamic types using a ValueProviderFactory http://www.dalsoft.co.uk/blog/index.php/2012/01/10/asp-net-mvc-3-improved-jsonvalueproviderfactory-using-json-net/

Solution 4:

Much like the accepted answer of a FormCollection, dynamic objects can also map to arbitrary JSON.

The only caveat is that you need to cast each property as the intended type, or MVC will complain.

Ex, in TS/JS:

var model: any = {};
model.prop1 = "Something";
model.prop2 = "2";

$http.post("someapi/thing", model, [...])

MVC C#:

[Route("someapi/thing")]
[HttpPost]
public object Thing(dynamic input)
{
    string prop1 = input["prop1"];
    string prop2 = input["prop2"];

    int prop2asint = int.Parse(prop2);

    return true;
}