在我的MVC 4应用程序中,我有一个可以拥有多个站点并可以订阅多个服务包的客户.我的视图模型的简短版本如下所示
public class SubscriptionModel { public int MemberId { get; set; } public List<SitePackage> SitePackges { get; set; } public SubscriptionModel() { SitePackges=new List<SitePackage>(); } } public class SitePackage { public int SiteId { get; set; } public List<PackageDisplayItem> LstPackageDisplayItems { get; set; } public SitePackage() { LstPackageDisplayItems=new List<PackageDisplayItem>(); } } public class PackageDisplayItem { public int PackageId { get; set; } [Display(Name = "Package")] public string Name { get; set; } [DataType(DataType.Date)] [Display(Name = "Start Date")] public DateTime? StartDate { get; set; } }
在我的控制器中,我填写模型,然后传递给View Model进行渲染
@using (@Html.BeginForm("CalculateCost","HelpDesk",FormMethod.Post,new { @class = "form",id = "PackageSubscription",name = "PackageSubscription" })) { @Html.HiddenFor(x=>x.MemberId) <table class="table"> @foreach (var site in Model.SitePackges) { <input name="SiteId" id="SiteId" type="hidden" value=@site.SiteId.ToString() /> <tr><td class="col-sm-3">@site.SiteId</td></tr> <tr> <th class="col-sm-3"> Name </th> <th class="col-sm-2"> Start Date </th> </tr> @Html.Partial("_Packages",site.LstPackageDisplayItems) }
我的部分观点是这样的
@model List<PackageDisplayItem> @for (int i = 0; i < Model.Count; i++) { @Html.HiddenFor(x => x[i].PackageId) <tr id="@Model[i].PackageId"> <td> @Html.DisplayFor(x => x[i].Name) </td> <td> @Html.TextBoxFor(x => x[i].StartDate,"{0:d MMM yyyy}",new { @class = "jquery_datepicker form-control",autocomplete = "off" }) </td> </tr> }
每个东西都很好,但在表单上,模型绑定器不绑定SitePackges列表,其计数始终为0.我的控制器具有以下签名.
[HttpPost] public ActionResult CalculateCost(SubscriptionModel subscriptionModel ) { var receivedModel = subscriptionModel; }
不确定我设计的模型是否是处理此要求的最佳方法(要求是显示单个站点,下方显示包,然后显示第二个站点和包等).控件似乎生成了唯一的索引.
Jquery Post
function SubmitForm() { console.log($("#PackageSubscription").serialize()); $.ajax({ url: '/HelpDesk/CalculateCost',cache: false,dataType: 'json',data: $("#PackageSubscription").serialize(),type: 'POST',success: function (data) { } });
}
我将不胜感激任何帮助.谢谢
解决方法
您当前的实现是渲染输入,如下所示:
<input ... name="[0].Name" .../> <input ... name="[1].Name" .../>
但为了绑定到你的模型,他们需要看起来像这样:
<input ... name="SitePackges[0].LstPackageDisplayItems[0].Name" .../> <input ... name="SitePackges[0].LstPackageDisplayItems[1].Name" .../> <input ... name="SitePackges[1].LstPackageDisplayItems[0].Name" .../> <input ... name="SitePackges[1].LstPackageDisplayItems[1].Name" .../>
答:您需要在嵌套for循环中呈现控件
for(int i = 0; i < Model.SitePackges.Count; i++) { @Html.HiddenFor(m => m.SitePackges[i].SiteId) for(int j = 0; j < Model.SitePackges[i].LstPackageDisplayItems.Count; j++) { @Html.TextBoxFor(m => m.SitePackges[i].LstPackageDisplayItems[j].Name) } }
B:或为您的模型类型使用自定义EditorTemplates
查看/共享/ EditorTemplates / SitePackage.cshtml
@model SitePackage @Html.HiddenFor(m => m.SiteId) @Html.EditorFor(m => m.LstPackageDisplayItems)
查看/共享/ EditorTemplates / PackageDisplayItem.cshtml
@model PackageDisplayItem @Html.TextBoxFor(m => m.Name)
并在主视图中
@model SubscriptionModel @using (@Html.BeginForm()) { @Html.HiddenFor(m => m.MemberId) @Html.EditorFor(m => m.SitePackges) <input type="submit" /> }