I have a form which I need to submit via ajax is submitting but not binding to the model.
My jquery source code is as below
function SubmitForm() {
console.log($("#PackageSubscription").serialize());
$.ajax({
url: '/HelpDesk/CalculateCost',
cache: false,
processData: false,
data: $("#PackageSubscription").serialize(),
type: 'POST',
success: function (data) {
}
});
}
Exactly the same form does bind when I use the standard mvc submit (synchronous ) via submit button.
Interestingly the console log has all the form values and they are exactly the same when we submit the form synchronously ( Console log string from ajax call and form values from fiddler request inspector are exactly the same)
some example data is like
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=
and my viewmodel looks like
public class PpmTypePackageSubscriptionModel
{
public int MemberId { get; set; }
public DateTime TimeStamp { get; set; }
public List<SitePackage> SitePackges { get; set; }
public double TotalCost { get; set; }
public PpmTypePackageSubscriptionModel()
{
SitePackges=new List<SitePackage>();
}
}
public class SitePackage
{
public int SiteId { get; set; }
public int SizeIndicator { get; set; }
public string Site { get; set; }
public List<PackageDisplayItem> LstPackageDisplayItems { get; set; }
public SitePackage()
{
LstPackageDisplayItems=new List<PackageDisplayItem>();
}
}
See below the mark up of 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)
<table class="table table-responsive table-condensed table-hover table-striped">
@for (int i = 0; i < Model.SitePackges.Count; i++)
{
<tr>
<td class="siteHeading">
@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)
</td>
</tr>
<tr>
<th class="col-sm-3">
Name
</th>
<th class="col-sm-2">
Subscribe
</th>
<th class="col-sm-2">
Last Service Date If Known
</th>
<th class="col-sm-2">
Proposed Date
</th>
</tr>
for (int j = 0; j < Model.SitePackges[i].LstPackageDisplayItems.Count; j++)
{
<tr>
<td>
@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)
</td>
<td>
@Html.RadioButtonFor(x => x.SitePackges[i].LstPackageDisplayItems[j].IsSubscribed, true, new { @class = "pull-left " })<label class="pull-left">Yes </label>
@Html.RadioButtonFor(x => x.SitePackges[i].LstPackageDisplayItems[j].IsSubscribed, false, new { @class = "pull-left" })<label class="pull-left">No</label>
</td>
<td>
@Html.TextBoxFor(x => x.SitePackges[i].LstPackageDisplayItems[j].LastServiceDate, "{0:d MMM yyyy}", new { @class = "jquery_datepicker form-control", autocomplete = "off" })
</td>
<td>
@Html.TextBoxFor(x => x.SitePackges[i].LstPackageDisplayItems[j].ProposedDate, "{0:d MMM yyyy}", new { @class = "jquery_datepicker form-control", autocomplete = "off" })
</td>
</tr>
}
}
</table>
<div class="row">
<div class="col-sm-3"><p>Parking Availability</p></div>
<div class="col-sm-5">
<select id="ParkingAvailability" class="form-control" name="ParkingAvailability">
<option value="1">Free Carpark</option>
<option value="2">Paid Carpark</option>
</select>
</div>
</div>
<div class="row">
<div class="col-sm-3"><p>Access Time</p></div><div class="col-sm-5"> <input class="form-control" name="SiteContactEmail" value="0900-1500 MonSat">
</div
</div>
<div class="row">
<div class="col-sm-3">
<input class="btn btn-primary" @*type="submit"*@ onclick="SubmitForm(); return false;" value="Calculate Cost" />
</div>
<div class="col-sm-5">
<span id="totalCost" class="hide form-control"></span>
</div>
</div>
<div class="row">
<div class="col-sm-5 col-sm-offset-3">
<input class="btn btn-success" type="submit" value="Submit For Approval" />
<input class="btn btn-danger" type="submit" value="Cancel Signup" />
</div>
</div>
}
My main view has the following mark up
<div id="tabs">
<ul>
<li><a href="#tabs-1">Member Sites </a></li>
<li><a href="#tabs-2">Services and Packages</a></li>
</ul>
<div id="tabs-1">
@Html.Partial("_MemberSites")
</div>
<div id="tabs-2">
@Html.Action("GetAllPpmTypePackages", new { @id = @Model.MemberNumber })
</div>
</div>
And my action methods looks like this
[HttpGet]
public ActionResult GetAllPpmTypePackages(int id)
{
// Processing to create the viewmodel and pass to view
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CalculateCost(PpmTypePackageSubscriptionModel ppmTypePackageSubscriptionModel)
{
// Processing
}