I am trying to use Steve Sanderson's blog post regarding binding collection items to a model. However, I'm seeing some weird behavior that I can't find an answer for in the post or other discussions.
In my model BankListMaster, I have an ICollection object of a separate model BankAgentId. BankListMaster and BankListAgentId have a one-to-many relationship in our SQL database.
I am running into the issue on the Edit page. When the page loads, the three agent Ids we currently have associated with the BankListMaster item I'm working with load properly. However, if I hit "Save", I see that the ICollection object (bankListAgentId) has a count of three items, but each respective field contains a null value.
If I select the Add another, then, following the instructions on the blog post, the Ajax calls a partial view which is appended to the table properly.
Now if I hit "Save", I see that the ICollection object count has increased by one item to a count of 4. All the items that were originally loaded with the GET again contain null field values, but the AgentId and StateCode fields for the newly appended item contain the correct information (all other fields for the new item are null, however).
Still relatively new to ASP MVC, so I'm not sure what is going on or what direction to look.
Here is the form from the main view. I've tried this with and without the @Html.Hidden items and received the same results.
@model Monet.Models.BankListMaster
@{
ViewBag.Title = "Edit";
}
<fieldset>
<legend>Stat(s) Fixed</legend>
<table id="fixedRows">
<thead>
<tr>
<th>State Code</th>
<th>Agent ID</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.Fixed.Count; i++)
{
using (Html.BeginCollectionItem("BankListAgentId"))
{
@Html.HiddenFor(m => Model.Fixed[i].BankID)
@Html.HiddenFor(m => Model.Fixed[i].TableId)
@Html.HiddenFor(m => Model.Fixed[i].FixedOrVariable)
<tr>
<td>
@Html.DropDownListFor(m => Model.Fixed[i].StateCode,
(SelectList)ViewBag.StateCodeList, Model.Fixed[i].StateCode)
</td>
<td>
@Html.TextBoxFor(m => Model.Fixed[i].AgentId)
@Html.ValidationMessageFor(m => Model.Fixed[i].AgentId)
</td>
<td>
<a href="javascript:void(0)" class="deleteRow">delete</a>
</td>
@*<td><a href="#" onclick="$('#item-@Model.AgentId').parent().remove();" style="float:right;">Delete</a></td>*@
</tr>
}
}
</tbody>
</table>
<br />
<a href="javascript:void(0)" class="addFixed">Add Another</a>
</fieldset>
Here is the partial view. Again, I've tried with and without the @Html.Hidden items and received the same result.
@model Monet.Models.BankListAgentId
@{
Layout = null;
}
@using (Html.BeginCollectionItem("BankListAgentId"))
{
@Html.HiddenFor(model => model.TableId)
@Html.HiddenFor(model => model.BankID)
@Html.HiddenFor(model => model.FixedOrVariable)
<tr>
<td>
@Html.DropDownListFor(model => model.StateCode,
(SelectList)ViewBag.StateCodeList, Model.StateCode)
</td>
<td>
@Html.EditorFor(model => model.AgentId)
@Html.ValidationMessageFor(model => model.AgentId)
</td>
<td>
<a href="javascript:void(0)" class="deleteRow">delete</a>
</td>
@*<td><a href="#" onclick="$('#item-@Model.AgentId').parent().remove();" style="float:right;">Delete</a></td>*@
</tr>
}
Here is the Ajax call
$(document).ready(function () {
$(".addFixed").click(function () {
$.ajax({
url: '@Url.Action("BlankFixedRow", "BankListMaster")',
dataType: 'html',
cache: false,
success: function (html) {
$("#fixedRows > tbody").append('<tr>' + html + '</tr>');
}
});
});
});
Here is the controller method that calls the partial view
public ViewResult BlankFixedRow()
{
SelectList tmpList = new SelectList(new[] { "AL", "AK", "AS", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NA", "NM", "NY", "NC", "ND", "MP", "OH", "OK", "OR", "PW", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "US", "VT", "VI", "VA", "WA", "WV", "WI", "WY" });
ViewBag.StateCodeList = tmpList;
return View("FixedPartialView", new BankListAgentId());
}
This is the BankListMaster model
public partial class BankListMaster
{
public BankListMaster()
{
this.BankListAttachments = new HashSet<BankListAttachments>();
this.BankListAgentId = new HashSet<BankListAgentId>();
}
public int ID { get; set; }
public string BankName { get; set; }
public string LastChangeOperator { get; set; }
public Nullable<System.DateTime> LastChangeDate { get; set; }
public virtual ICollection<BankListAttachments> BankListAttachments { get; set; }
public virtual ICollection<BankListAgentId> BankListAgentId { get; set; }
}
And this is the BankListAgentId model
public partial class BankListAgentId
{
public string AgentId { get; set; }
public int BankID { get; set; }
public string FixedOrVariable { get; set; }
public string StateCode { get; set; }
public int TableId { get; set; }
public virtual BankListMaster BankListMaster { get; set; }
}
Here is the what is sent from the form on the post back to the controller via fiddler. The items that are indexed 1, 2, and 3 are the items originally pulled from the database. The last item was added via the jQuery/Ajax call to the partial view.
