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++) { @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 for (int j = 0; j < Model.SitePackges[i].LstPackageDisplayItems.Count; j++) { @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());
Interesting Posts