Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery 将动态json对象传递给C#MVC控制器_Jquery_Json_Asp.net Mvc 3 - Fatal编程技术网

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

Jquery 将动态json对象传递给C#MVC控制器,jquery,json,asp.net-mvc-3,Jquery,Json,Asp.net Mvc 3,我正在使用.NET4、MVC3和jQueryV1.5进行一些工作 我有一个JSON对象,它可以根据调用它的页面而改变。我想将对象传递给控制器 { id: 1, title: "Some text", category: "test" } 我知道如果我创建一个自定义模型,例如 [Serializable] public class myObject { public int id { get; set; } public string title { get; set; }

我正在使用.NET4、MVC3和jQueryV1.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#模型添加项目

这真的可能吗?我尝试将对象映射到字典,但数据的值最终将为null


感谢

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

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

另一种解决方案是在模型中使用动态类型。我写了一篇关于如何使用ValueProviderFactory绑定到动态类型的博客文章

如果使用如下包装器,您可以提交JSON并将其解析为动态:

JS:

C#,输入模型:

/// <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; }
}
在JS端添加包装器很烦人,但是如果你能克服它,它会简单而干净

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

这不是很难-请遵循本文:

与FormCollection的公认答案类似,动态对象也可以映射到任意JSON

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

例如,在TS/JS中:

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

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


太棒了,这么简单又有效的答案。谢谢如果传回的对象有子对象,这个解决方案会变得非常混乱。@ChrisMoschini如果对象有子对象,你会怎么做?@user1477388包装的动态方法:为什么不将对象作为原始JSON字符串传回,例如
JsonResult-JsonAction(string-JSON)
并使用NewtonSoft Json.NET反序列化到动态对象?相关/重复:如果您创建一个虚拟类作为要传回的动态ViewModel的包装器对象,并为发送到服务器的实际数据创建一个单独的动态属性,则此解决方案将非常有效。控制器的参数需要是一个实际的类,但是因为它的任何子类都可以是动态的,所以可以使用虚拟包装器来解决这个限制。很好,如果这样做很好。如果可以的话,不需要使用JSON.Net。谢谢
public JsonResult Edit(JsonDynamicWrapper json)
{
    dynamic data = json.d; // Get the actual data out of the object

    // Do something with it

    return Json(null);
}
var model: any = {};
model.prop1 = "Something";
model.prop2 = "2";

$http.post("someapi/thing", model, [...])
[Route("someapi/thing")]
[HttpPost]
public object Thing(dynamic input)
{
    string prop1 = input["prop1"];
    string prop2 = input["prop2"];

    int prop2asint = int.Parse(prop2);

    return true;
}