Asp.net mvc ASP.NET MVC如何将JSON对象作为参数从视图传递到控制器
我有一个复杂的JSON对象,它被发送到视图时没有任何问题(如下所示),但我无法确定在通过AJAX调用将此数据传递回控制器时如何将其序列化回.NET对象。各部分的详情如下Asp.net mvc ASP.NET MVC如何将JSON对象作为参数从视图传递到控制器,asp.net-mvc,json,Asp.net Mvc,Json,我有一个复杂的JSON对象,它被发送到视图时没有任何问题(如下所示),但我无法确定在通过AJAX调用将此数据传递回控制器时如何将其序列化回.NET对象。各部分的详情如下 var ObjectA = { "Name": 1, "Starting": new Date(1221644506800), "Timeline": [ { "StartTime": new Date(1221644
var ObjectA = {
"Name": 1,
"Starting": new Date(1221644506800),
"Timeline": [
{
"StartTime": new Date(1221644506800),
"GoesFor": 200
}
,
{
"StartTime": new Date(1221644506800),
"GoesFor": 100
}
]
};
我不确定如何将这个对象传递给控制器方法,我在下面有这个方法,其中Timelines对象使用属性镜像上面的JS对象
public JsonResult Save(Timelines person)
我使用的jQuery是:
var encoded = $.toJSON(SessionSchedule);
$.ajax({
url: "/Timeline/Save",
type: "POST",
dataType: 'json',
data: encoded,
contentType: "application/json; charset=utf-8",
beforeSend: function() { $("#saveStatus").html("Saving").show(); },
success: function(result) {
alert(result.Result);
$("#saveStatus").html(result.Result).show();
}
});
我看到过这个问题,它与我没有使用表单来处理数据的问题相似,但不完全相同。
我还看到过使用“JsonFilter”手动反序列化JSON的引用,但我想知道是否有一种方法可以通过ASP.NET MVC在本机实现?或者,以这种方式传递数据的最佳实践是什么?你说“我没有使用表单来处理数据。”但你是在写一篇博文。因此,实际上,您正在使用一个表单,即使它是空的
$.ajax告诉jQuery服务器将返回什么类型,而不是传递什么。POST只能传递一个表单。jQuery并将其作为查询字符串传递。从文档中:
要发送到服务器的数据。它是
已转换为查询字符串(如果不是)
已经是一串了。它被附加到
获取请求的url。请参阅processData
选项,以防止自动执行此操作
处理。对象必须是键/值
对。如果值是数组,则jQuery
用相同的值序列化多个值
键,即{foo:[“bar1”,“bar2”]}
变成“&foo=bar1&foo=bar2”
因此:
反序列化,不过您需要.NET对象具有与javascript对象类似的签名。此外,还有一个反序列化对象
方法,它只生成一个普通的对象
。然后可以使用反射来获取所需的属性
如果您的控制器采用表单集合
,并且您没有向数据添加任何其他内容
,则json应采用格式[0]
:
public ActionResult Save(FormCollection forms) {
string json = forms[0];
// do your thing here.
}
编辑:
随着MVC 3的到来,不再需要这种方法,因为它将自动处理-
您可以使用此ObjectFilter:
public class ObjectFilter : ActionFilterAttribute {
public string Param { get; set; }
public Type RootType { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext) {
if ((filterContext.HttpContext.Request.ContentType ?? string.Empty).Contains("application/json")) {
object o =
new DataContractJsonSerializer(RootType).ReadObject(filterContext.HttpContext.Request.InputStream);
filterContext.ActionParameters[Param] = o;
}
}
}
然后,您可以将其应用于控制器方法,如下所示:
[ObjectFilter(Param = "postdata", RootType = typeof(ObjectToSerializeTo))]
public JsonResult ControllerMethod(ObjectToSerializeTo postdata) { ... }
因此,基本上,如果帖子的内容类型是“application/json”,这将启动并将值映射到您指定的类型的对象。此答案是DaRKoN_使用对象过滤器的答案的后续:
[ObjectFilter(Param = "postdata", RootType = typeof(ObjectToSerializeTo))]
public JsonResult ControllerMethod(ObjectToSerializeTo postdata) { ... }
我在弄清楚如何将多个参数发送到一个动作方法时遇到了一个问题,其中一个是json对象,另一个是普通字符串。我是MVC新手,我刚刚忘记我已经用非ajaxed视图解决了这个问题
如果一个视图上需要两个不同的对象,我会怎么做。我将创建一个ViewModel类。假设我需要person对象和address对象,我会执行以下操作:
public class SomeViewModel()
{
public Person Person { get; set; }
public Address Address { get; set; }
}
然后将视图绑定到某个ViewModel。您可以用JSON做同样的事情
[ObjectFilter(Param = "jsonViewModel", RootType = typeof(JsonViewModel))] // Don't forget to add the object filter class in DaRKoN_'s answer.
public JsonResult doJsonStuff(JsonViewModel jsonViewModel)
{
Person p = jsonViewModel.Person;
Address a = jsonViewModel.Address;
// Do stuff
jsonViewModel.Person = p;
jsonViewModel.Address = a;
return Json(jsonViewModel);
}
然后在视图中,您可以使用JQuery的简单调用,如下所示:
var json = {
Person: { Name: "John Doe", Sex: "Male", Age: 23 },
Address: { Street: "123 fk st.", City: "Redmond", State: "Washington" }
};
$.ajax({
url: 'home/doJsonStuff',
type: 'POST',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify(json), //You'll need to reference json2.js
success: function (response)
{
var person = response.Person;
var address = response.Address;
}
});
$.ajax({
type: "POST",
url: "SomeURL",
data: $.toDictionary(yourComplexJSONobject),
success: function() { ... },
error: function() { ... }
});
一个简单的jQuery插件带来了不同的体验
尽管这个问题的答案早就应该得到了,但我还是发布了一个不错的解决方案,它让将复杂的JSON发送到Asp.net MVC控制器操作变得非常简单,因此它们都是模型绑定到任何强类型参数的
这个插件同样支持日期,因此它们可以毫无问题地转换为对应的日期时间
您可以在我检查问题的地方找到所有细节,并提供完成此任务所需的代码
你所要做的就是在客户端使用这个插件。Ajax请求如下所示:
var json = {
Person: { Name: "John Doe", Sex: "Male", Age: 23 },
Address: { Street: "123 fk st.", City: "Redmond", State: "Washington" }
};
$.ajax({
url: 'home/doJsonStuff',
type: 'POST',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify(json), //You'll need to reference json2.js
success: function (response)
{
var person = response.Person;
var address = response.Address;
}
});
$.ajax({
type: "POST",
url: "SomeURL",
data: $.toDictionary(yourComplexJSONobject),
success: function() { ... },
error: function() { ... }
});
但这只是整个问题的一部分。现在我们可以将复杂的JSON发布回服务器,但由于它将被模型绑定到一个复杂类型,该类型可能在属性上具有验证属性,所以在这一点上可能会失败。我有一本书。我的解决方案利用了jqueryajax功能,结果可以是成功的,也可以是错误的(如上面的代码所示)。因此,当验证失败时,error
函数将按预期调用。回应Dan的上述评论:
我使用这个方法来实现
同样的事情,但出于某种原因我
我的电脑有个例外
ReadObject方法:“应为元素
遇到命名空间“”中的“root”…错误
名称为“”、命名空间为“”的“无”
你知道为什么吗4月6日丹·阿普利亚德
17点57分10分
我也有同样的问题(MVC3build3.0.11209.0),下面的帖子帮我解决了这个问题。基本上,json序列化程序正在尝试读取一个不在开头的流,因此将该流重新定位为0“修复”它
回答很好,不确定为什么这不是公认的答案,当然帮了我的忙…我使用此方法实现了同样的事情,但由于某种原因,我在ReadObject方法上遇到了一个异常:“预期来自命名空间“”的元素“root”…遇到了名为“”、命名空间“”的“None”知道为什么吗?这个答案也帮了我的忙。谢谢。如何添加更多非json的操作参数?JsonResult blah(字符串s,人员p)。我能够将json对象绑定到person p,但我不知道如何将字符串s与json对象一起传递。添加我的发现作为后续答案。谢谢你的帮助,达康!这实际上与向服务器发送JSON的细节无关,但这是一个很好的例子,说明了它有多么复杂