jquery ajax表单提交不会绑定mvc 4中的复杂模型

我有一个表单,我需要通过ajax提交提交但不绑定到模型。

我的jquery源代码如下

function SubmitForm() { console.log($("#PackageSubscription").serialize()); $.ajax({ url: '/HelpDesk/CalculateCost', cache: false, processData: false, data: $("#PackageSubscription").serialize(), type: 'POST', success: function (data) { } }); 

}

当我通过提交按钮使用标准mvc submit(同步)时,完全相同的表单会绑定。

有趣的是,控制台日志具有所有表单值,并且当我们同步提交表单时它们完全相同(来自ajax调用的控制台日志字符串和来自fiddler请求检查器的表单值完全相同)

一些示例数据就像

 MemberId=12345678 &SitePackges[0].SiteId=50 &SitePackges[0].SizeIndicator=2 &SitePackges[0].LstPackageDisplayItems[0].PackageId=4 &SitePackges[0].LstPackageDisplayItems[0].Name=PAT and Emergency Lighting &SitePackges[0].LstPackageDisplayItems[0].IsSubscribed=True &SitePackges[0].LstPackageDisplayItems[0].LastServiceDate= &SitePackges[0].LstPackageDisplayItems[0].ProposedDate= &SitePackges[0].LstPackageDisplayItems[1].PackageId=6 &SitePackges[0].LstPackageDisplayItems[1].Name=Fire Alarm and Extinguishers &SitePackges[0].LstPackageDisplayItems[1].IsSubscribed=True &SitePackges[0].LstPackageDisplayItems[1].LastServiceDate= &SitePackges[0].LstPackageDisplayItems[1].ProposedDate= 

和我的viewmodel看起来像

 public class PpmTypePackageSubscriptionModel { public int MemberId { get; set; } public DateTime TimeStamp { get; set; } public List SitePackges { get; set; } public double TotalCost { get; set; } public PpmTypePackageSubscriptionModel() { SitePackges=new List(); } } public class SitePackage { public int SiteId { get; set; } public int SizeIndicator { get; set; } public string Site { get; set; } public List LstPackageDisplayItems { get; set; } public SitePackage() { LstPackageDisplayItems=new List(); } } 

请参见下面的View标记

 @using Booker.WebUI.Models @model PpmTypePackageSubscriptionModel @using (@Html.BeginForm("CalculateCost", "HelpDesk", FormMethod.Post, new { @class = "form", id = "PackageSubscription", name = "PackageSubscription" })) { @Html.AntiForgeryToken() @Html.HiddenFor(x => x.MemberId)  @for (int i = 0; i < Model.SitePackges.Count; i++) {  for (int j = 0; j < Model.SitePackges[i].LstPackageDisplayItems.Count; j++) {  } } 
@Html.HiddenFor(x => x.SitePackges[i].SiteId) @Html.DisplayFor(x => x.SitePackges[i].Site) @Html.HiddenFor(x => x.SitePackges[i].SizeIndicator) @Html.DisplayFor(x => x.SitePackges[i].SizeIndicator)
Name Subscribe Last Service Date If Known Proposed Date
@Html.HiddenFor(x => x.SitePackges[i].LstPackageDisplayItems[j].PackageId) @Html.HiddenFor(x => x.SitePackges[i].LstPackageDisplayItems[j].Name) @Html.DisplayFor(x => x.SitePackges[i].LstPackageDisplayItems[j].Name) @Html.RadioButtonFor(x => x.SitePackges[i].LstPackageDisplayItems[j].IsSubscribed, true, new { @class = "pull-left " }) @Html.RadioButtonFor(x => x.SitePackges[i].LstPackageDisplayItems[j].IsSubscribed, false, new { @class = "pull-left" }) @Html.TextBoxFor(x => x.SitePackges[i].LstPackageDisplayItems[j].LastServiceDate, "{0:d MMM yyyy}", new { @class = "jquery_datepicker form-control", autocomplete = "off" }) @Html.TextBoxFor(x => x.SitePackges[i].LstPackageDisplayItems[j].ProposedDate, "{0:d MMM yyyy}", new { @class = "jquery_datepicker form-control", autocomplete = "off" })

Parking Availability

Free Carpark Paid Carpark

Access Time

</div

}

我的主要观点有以下标记

 
@Html.Partial("_MemberSites")
@Html.Action("GetAllPpmTypePackages", new { @id = @Model.MemberNumber })

我的行动方法看起来像这样

  [HttpGet] public ActionResult GetAllPpmTypePackages(int id) { // Processing to create the viewmodel and pass to view } [HttpPost] [ValidateAntiForgeryToken] public ActionResult CalculateCost(PpmTypePackageSubscriptionModel ppmTypePackageSubscriptionModel) { // Processing } 

如果我理解正确,表单不会更新,因为您没有对从ajax响应收到的数据做任何事情。

您应该在ajax success函数中绑定结果。 Ajax是异步的,因此数据被发布,但响应不一定立即。 当成功接收到响应(没有超时或连接丢失等)时,ajax调用将转到success函数,并且响应数据在您的情况下存储在变量“data”中。

尝试执行以下操作:

 function SubmitForm() { console.log($("#PackageSubscription").serialize()); $.ajax({ url: '/HelpDesk/CalculateCost', cache: false, processData: false, data: $("#PackageSubscription").serialize(), type: 'POST', success: function (data) { alert(data); // This will only show the response for you, use for debugging only $("#MemberId").value(data.MemberId); } }); 

从ajax中删除processData:false。 然后它肯定会与你的模型绑定。 请阅读以下内容:

processData(默认值:true)类型:Boolean默认情况下,作为对象传入数据选项的数据(技术上,不是字符串)将被处理并转换为查询字符串,适合默认的内容类型“应用程序” / X WWW的窗体-urlencoded”。 如果要发送DOMDocument或其他未处理的数据,请将此选项设置为false。

这可能是serialize()函数的问题。

尝试使用JSON.stringify。

  

控制器:

 [HttpPost] public ActionResult AjaxForm(DocOrderSecurityOutViewModel model) { // magic } 

在Global.asax中:

  ValueProviderFactories.Factories.Add( new JsonValueProviderFactory());