MVC2 通过 json 从视图控制器发送集合
我已经在论坛上找了两天了,找不到好的答案,所以我就发布它。
我似乎在将 JSON 发回控制器进行保存时遇到问题。 JSON 应该映射到模型视图,但它不断获取默认(构造函数)值,而不是来自 POST 的值。
我们有一系列 JS 小部件,其中包含一个带有 json 的数据字段。我们在客户端的这些小部件对象中进行所有数据操作。当用户想要保存时,我们从涉及的小部件中获取所需的数据,并将其放入与 ViewModel 匹配的另一个 JSON 对象中,并将其 POST 回服务器。
例如:
$("#Save").click(function () {
if (itemDetails.preparedForSubmit() && itemConnections.preparedForSubmit()) {
itemComposite.data.Details = itemDetails.data;
itemComposite.data.Connections= itemConnections.data;
$.post(MYURL, itemComposite.data);
} else {
alert("failed to save");
}
});
preparedForSubmit() 方法简单地执行诸如客户端可能需要执行的任何验证检查或最后一刻格式化之类的操作。
itemDetails 小部件数据与 ViewModel 匹配。
itemConnections 小部件数据与 ViewModel 的集合相匹配。
控制器如下所示:
[HttpPost]
virtual public JsonResult SaveItemDetailsComposite(ItemComposite inItemData)
{
if (ModelState.IsValid)
{
try
{
_Mapper.Save(itemComposite.Details , itemComposite.Connections);
return Json(true);
}
catch (Exception ex)
{
_log.Error("Exception " + ex.InnerException.Message);
throw;
}
}
return Json(SiteMasterUtilities.CreateValidationErrorResponse(ModelState));
}
ItemComposite 类是一个简单的视图模型,其中包含单个 itemDetails 对象和 itemConnections 的集合。当它返回数据到这里时,它只是获取默认数据,就像获取一个新的 ItemComposite 一样,而不是转换 POST 数据。
在 Firebug 中我看到数据已发布。虽然它看起来很奇怪,但在 firebug 中没有自动格式化。
I've been looking on forums for 2 days now and can't find a good answer so I'll just post it.
I appear to be having a problem posting JSON back to the controller to save. The JSON should map to model view but it keeps getting default(constructor)values rather then the values from the POST.
We have a series of JS widgets that contain a data field with json in them. We do all our data manipulation in these widget objects on the client side. When a user wants to save we grab the data we need from the widgets involved and we put it into another JSON object that matches a ViewModel and POST that back to the server.
For example:
$("#Save").click(function () {
if (itemDetails.preparedForSubmit() && itemConnections.preparedForSubmit()) {
itemComposite.data.Details = itemDetails.data;
itemComposite.data.Connections= itemConnections.data;
$.post(MYURL, itemComposite.data);
} else {
alert("failed to save");
}
});
The preparedForSubmit() method simple does stuff like any validation checks or last minute formatting you might need to do client side.
The itemDetails widgets data matches a ViewModel.
The itemConnections widgets data matches a collection of ViewModels.
The Controller looks like this:
[HttpPost]
virtual public JsonResult SaveItemDetailsComposite(ItemComposite inItemData)
{
if (ModelState.IsValid)
{
try
{
_Mapper.Save(itemComposite.Details , itemComposite.Connections);
return Json(true);
}
catch (Exception ex)
{
_log.Error("Exception " + ex.InnerException.Message);
throw;
}
}
return Json(SiteMasterUtilities.CreateValidationErrorResponse(ModelState));
}
The ItemComposite Class is a simple View Model that contains a single itemDetails object and a collection of itemConnections. When it returns data to here it is just getting the default data as if it got a new ItemComposite rather than converting the POST data.
in Firebug I see the data is posted. Although it looks weird not automatically formatted in firebug.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您是说 itemComposite.data 被格式化为 JSON 对象吗?如果是这样,我很确定您必须先对其进行反序列化,然后才能将其强制转换为对象。像这样的东西:
Are you saying that itemComposite.data is formatted as a JSON object? If so, I'm pretty sure you're going to have to de-serialize it before you can cast it to your object. Something like:
您可能需要研究像 JSON.NET 这样的框架,以确保您的数据在提供给您的 Action 时能够正确序列化。
JSON.NET 似乎是主流框架之一: http://json.codeplex.com /releases/view/43775
希望这有帮助。
科里
You may want to look into a framework like JSON.NET to ensure that your data is being serialized properly when it gets supplied to your Action.
JSON.NET seems like it's one of the main stream frameworks: http://json.codeplex.com/releases/view/43775
Hope this helps.
Cory
您还可以在 WCF 中使用 JSON 序列化器: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx
所以不允许我将两个链接放在一个答案中,对于分开的答案感到抱歉。
You could also use the JSON Serializer in WCF: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx
SO wouldn't let me put both links in one answer, sorry for the split answer.
谢谢大家。我想我已经解决了我的问题,并且我很确定我有四个问题。在很大程度上,我遵循了 Steveguys 的建议,并阅读了这篇文章的更多内容: http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument .aspx
使用 jQuery 的 post() 方法并指定 json 作为类型似乎并没有真正将其作为 json 发送。通过使用 ajax() 方法并指定 json,它将其作为 json 发送。
JSON.serialize() 方法还需要干净地发送 json。
我的 ViewModel 设计也是一个大问题。我们正在使用 MS 代码分析构建垃圾,它不希望我在 ViewModel 中为我的集合设置设置器。所以我来自 java/hibernate 世界,认为它不需要它们绑定,它会神奇地作为序列化对象出现。有一次我只是抑制了错误并重置了我的设置器。我现在正在控制器中获取集合。
我相信使用 MVC2 Future 的价值提供者正在做一些事情,但它仍然不能稳健地转换 json 日期,所以我仍在研究实现这一点的最佳方法。
我希望我的问题对其他人有帮助。
更新:使用此方法更新数据集合似乎非常慢。包含 200 个条目且每个条目有 8 个字段的集合需要 3 分钟才能到达控制器。只需 1 或 2 个条目即可花费很少的时间。我唯一知道的是这里发生的事情是数据绑定到模型视图。我不知道MVC2是否提供了一种简单的方法来发送这么多数据并绑定它。
Thanks everyone. I think I have solved my problem and I'm pretty sure that I had four issues. For the most part I followed thatSteveguys's suggestion and read more on this article: http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx
Using jQuery's post() method and specifying json as the type didn't seem to actually send it as json. By using the ajax() method and specifying json it sent it as json.
The JSON.serialize() method was also need to cleanly send over the json.
Also my ViewModel design was a big problem. We are using the MS code analytic build junk and it didn't want me having a setter for my collections in the ViewModel. So me being from a java/hibernate world, thought it didn't need them to bind and it would just come in as a serialized object magically. Once I just suppressed the error and reset up my setters. I am getting the collections now in my controller.
I believe using the MVC2 Future's Value Providers are doing something but it still doesn't convert json dates robustly, So I am still investigating the best way to do that.
I hope my issues help out others.
UPDATE: using this method to update collections of data appears to be super slow. A collection with 200 entries in it and 8 fields per entry takes 3 minutes to get to the controller. Just 1 or 2 entries take very little time. The only thing I know of that is happening between here is data binding to the model view. I don't know if MVC2 provides a easy way to send this much data and bind it.