In my MVC 4 application, I have a Client that can have several sites and can subscribe to several service packages. A short version of my view model looks below
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; } }
In my controller, I populate the model and then move on to the View Model for rendering
@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) }
My partial view is similar to
@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> }
Every thing looks great, but on the form blank, model binding is not a mandatory SitePackges list, and its score is always 0. My controller has the following signatures.
[HttpPost] public ActionResult CalculateCost(SubscriptionModel subscriptionModel ) { var receivedModel = subscriptionModel; }
I'm not sure that the model I developed is the best approach to solving this requirement (the requirement is to show one site, and below it shows the packages, and then the second site and packages, etc.). The controls seem to have unique indexes.
JQuery Post
function SubmitForm() { console.log($("#PackageSubscription").serialize()); $.ajax({ url: '/HelpDesk/CalculateCost', cache: false, dataType: 'json', data: $("#PackageSubscription").serialize(), type: 'POST', success: function (data) { } });
}
I would be grateful for any help. thanks