将序列化表格数据和附加数据发布到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 } }); 

需要注意的事项:

  1. 在你的AJAX请求中摆脱这个dataType: 'json'参数。 您正在使用ASP.NET MVC,并希望您从控制器操作返回Jsonresult,该操作成功将Content-Type响应标头设置为正确的值。 jQuery足够智能,可以使用此响应头的值并预处理将传递给AJAX请求的success回调的result变量。 所以在这种情况下你将获得一个javascript对象
  2. 由于您要在AJAX请求中向服务器发送JSON,因此需要正确指定contentType: application/json参数。 否则,您如何期望ASP.NET MVC知道客户端正在发送JSON并应用正确的模型绑定器? 顺便说一句,jQuery将发送的默认Content-Type请求标头是application/x-www-form-urlencoded ,因此如果您在POST请求中发送JSON有效负载,那将是冲突并违反协议。