将动态json对象传递给C#MVC控制器

时间:2011-02-16 22:31:42

标签: jquery json asp.net-mvc-3

我正在使用.Net 4,MVC 3和jQuery v1.5进行一些工作

我有一个JSON对象,可以根据调用它的页面进行更改。我想将对象传递给控制器​​。

{ id: 1, title: "Some text", category: "test" }

我明白如果我创建一个自定义模型,如

[Serializable]
public class myObject
{
    public int id { get; set; }
    public string title { get; set; }
    public string category { get; set; }
}

并在我的控制器中使用它,例如

public void DoSomething(myObject data)
{
    // do something
}

并使用jQuery的.ajax方法传递对象:

$.ajax({ 
    type: "POST", 
    url: "/controller/method", 
    myjsonobject,  
    dataType: "json", 
    traditional: true
});

这很好用,我的JSON对象映射到我的C#对象。我想做的是传递一个可能会改变的JSON对象。当它改变时,我不希望每次JSON对象改变时都要向我的C#模型添加项目。

这实际上可行吗?我尝试将对象映射到Dictionary,但数据的值最终会为null。

由于

5 个答案:

答案 0 :(得分:14)

假设接受输入的操作仅用于此特定目的,因此您可以使用FormCollection对象,然后将对象的所有json属性添加到字符串集合中。

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

答案 1 :(得分:9)

如果你使用这样的包装器,你可以提交JSON并将其解析为动态:

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#,控制器动作:

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

    // Do something with it

    return Json(null);
}

烦人的是在JS方面添加包装器,但是如果你可以通过它就简单而干净。

更新

您还必须切换到Json.Net作为默认的JSON解析器才能使其正常工作;在MVC4中无论出于何种原因,除了控制器序列化和反序列化之外,他们几乎用Json.Net取代了所有内容。

这不是很难 - 请按照这篇文章: http://www.dalsoft.co.uk/blog/index.php/2012/01/10/asp-net-mvc-3-improved-jsonvalueproviderfactory-using-json-net/

答案 2 :(得分:3)

使用自定义ModelBinder,您可以接收JsonValue作为操作参数。这基本上会为您提供一个动态类型的JSON对象,可以在客户端上创建您想要的任何形状。 this博客文章中概述了此技术。

答案 3 :(得分:2)

另一种解决方案是在模型中使用动态类型。我写过一篇关于如何使用ValueProviderFactory绑定到动态类型的博客文章http://www.dalsoft.co.uk/blog/index.php/2012/01/10/asp-net-mvc-3-improved-jsonvalueproviderfactory-using-json-net/

答案 4 :(得分:2)

就像FormCollection的公认答案一样,动态对象也可以映射到任意JSON。

唯一的警告是您需要将每个属性强制转换为预期的类型,否则MVC会抱怨。

Ex,在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;
}