将序列化表格数据和附加数据发布到MVC控制器?
我正在尝试将一些POST请求发送到我的服务器的其他数据。 最初,我只发送了几种forms的信息:
$.ajax({ url: 'SaveAllDetails', type: 'POST', data: $('form').serialize(), dataType: 'json' });
和MVC控制器方法:
[HttpPost] public ActionResult SaveAllDetails([Bind(Prefix = "order")]ExistingOrderDetailsModel existingOrderDetailsModel, [Bind(Prefix = "task")]ExistingTaskDetailsModel existingTaskDetailsModel, [Bind(Prefix = "device")]DeviceDetailsModel deviceDetailsModel) { .... }
这很好用。 MVC的模型绑定器能够正确地反序列化URL编码的字符串。
现在,要求已经改变。 我需要发送一个额外的数据数组以及我的三个表单。 此数据数组不保存在表单中,也没有绑定前缀。 我需要在同一个Controller方法中完成所有操作,因为所有validation都需要在单个事务中执行。
所以,我现在有:
var subcomponentsGridRows = JSON.stringify(subcomponentsDetailsView.getAllGridData()); var existingOrderDetailsFormData = $('form#existingOrderDetailsForm').serialize(); var existingTaskDetailsFormData = $('form#existingTaskDetailsForm').serialize(); var deviceDetailsFormData = $('form#existingDeviceDetailsForm').serialize() $.ajax({ url: 'SaveAllDetails', type: 'POST', data: { existingOrderDetailsModel: existingOrderDetailsFormData, existingTaskDetailsModel: existingTaskDetailsFormData, deviceDetailsModel: deviceDetailsFormData, subcomponentsGridRows: subcomponentsGridRows }, dataType: 'json' });
这至少有一个原因不起作用。 每个表单都表示为URL编码的字符串。 subcomponentsGridRows是一个JSON结构。 据我所知,MVC模型绑定器无法一次性解密这两种类型的信息。
解决这个问题的好方法是什么?
您可能会发现following plugin
很有用。
以下是它对您有用的方式。 让我们首先通过定义视图模型来清理控制器操作:
public class MyViewModel { public ExistingOrderDetailsModel Order { get; set; } public ExistingTaskDetailsModel Task { get; set; } public DeviceDetailsModel Device { get; set; } public AdditionalRowsViewModel[] AdditionalRows { get; set; } }
在此示例中, AdditionalRowsViewModel
显然会保存您尝试传递给控制器操作的其他信息。
然后您的控制器操作将变为:
[HttpPost] public ActionResult SaveAllDetails(MyViewModel model) { .... }
好的,这一步是绝对必要的,只是当我看到控制器动作占用多于1个参数时,我只需定义一个视图模型。
最后让我们调整我们的AJAX调用:
$.ajax({ url: 'SaveAllDetails', type: 'POST', contentType: 'application/json', data: JSON.stringify({ order: $('form#existingOrderDetailsForm').serializeObject(), task: $('form#existingTaskDetailsForm').serializeObject(), device: $('form#existingDeviceDetailsForm').serializeObject(), additionalRows: subcomponentsDetailsView.getAllGridData() }), success: function(result) { // do something with the result of the AJAX call here } });
需要注意的事项:
- 在你的AJAX请求中摆脱这个
dataType: 'json'
参数。 您正在使用ASP.NET MVC,并希望您从控制器操作返回Jsonresult,该操作成功将Content-Type
响应标头设置为正确的值。 jQuery足够智能,可以使用此响应头的值并预处理将传递给AJAX请求的success
回调的result
变量。 所以在这种情况下你将获得一个javascript对象 - 由于您要在AJAX请求中向服务器发送JSON,因此需要正确指定
contentType: application/json
参数。 否则,您如何期望ASP.NET MVC知道客户端正在发送JSON并应用正确的模型绑定器? 顺便说一句,jQuery将发送的默认Content-Type请求标头是application/x-www-form-urlencoded
,因此如果您在POST请求中发送JSON有效负载,那将是冲突并违反协议。