I am getting null values of Model on Controller when I submit Ajax.BeginForm form. Model have another model inside (one to many relationship)
Here is my Sample View code (removed unnecessary things)
<table id="PageSortTable" class="travelads_business_rules" cellspacing="0">
<thead>
<tr valign="bottom">
<th>ID</th>
<th> </th>
<th> </th>
<th>Rule Name</th>
<th>Business</th>
<th>Region</th>
<th>Form</th>
<th>Company</th>
<th>Team</th>
<th>Language</th>
<th>Media</th>
<th>InsertLoc</th>
<th>Size</th>
<th>Access</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr valign="top">
<td class="col_a">
<span>@item.id</span>
</td>
<td class="col_b">
<a href="@(Url.Action("EditTravelAdsRule", new { id = item.id }))">
<img alt="Edit" class="tableItemImage" src="../../Content/Images/Edit-icon.PNG" title="Edit" />
</a><a href="@(Url.Action("DeleteTravelAdsRule", new { id = item.id }))">
<img alt="Delete" class="tableItemImage" src="../../Content/Images/delete-icon.PNG"
title="Delete" />
</a>
</td>
<td class="col_c">
<div class="tableButtonCell"><a href="#" onclick='DoExpandCollapsh("trMinimised@(item.id)")'>
<img alt="Details" class="tableItemImage" src="../../Content/Images/expand-icon.png"
title="Expand" /></a></div>
</td>
<td class="col_d"><span>@item.ad_rule_name</span></td>
<td class="col_f"><span>@item.business</span></td>
<td class="col_g"><span>@item.ad_region</span></td>
<td class="col_h"><span>@item.ad_form</span></td>
<td class="col_i"><span>@item.ad_company</span></td>
<td class="col_j"><span>@item.ad_team</span></td>
<td class="col_k"><span>@item.ad_language</span></td>
<td class="col_l"><span>@item.ad_media_id</span></td>
<td class="col_m"><span>@item.ad_insert_loc</span></td>
<td class="col_n"><span> </span></td>
<td class="col_o"><span>@item.access</span></td>
</tr>
<tr class="minimised" id='trMinimised@(item.id)'>
<td colspan="13">
@using (Ajax.BeginForm("_SaveGroupMatchs", null, new AjaxOptions { OnSuccess = "onSuccess", UpdateTargetId = "msgResult", LoadingElementId = "msgLoading" }, new { @id = "SaveForm"}))
{
<div class="detail">
<div class="table_header">
<span class="col_a">Group</span> <span class="col_b">Group Scope</span> <span class="col_c">
Seq</span> <span class="col_d"> </span> <span class="col_e">ID</span> <span
class="col_f">Match Location</span> <span class="col_g">Target Field</span>
<span class="col_h">Match Type</span> <span class="col_i">Set Name</span>
</div>
<!-- Loop for matches -->
<!-- start GROUP -->
<div class="group">
@foreach (var item1 in item.lstMatches)
{
<div id="rule@(item.id)_divRuleGroup_@(item1.match_group_num)">
<header id="header_rule_Group"><span class="col_a">@(item1.match_group_num) </span><span class="col_b">
@Html.DropDownListFor(model => item1.match_group_scope, new SelectList((List<QIOnlineMVC3.Helpers.clsGroupScope>)QIOnlineMVC3.Helpers.General.GetALLGroupScope(), "GroupNum", "GroupScope", item1.match_group_num))
</span></header>
<div class="match">
<span class="col_c">@(item1.match_group_seq) @Html.HiddenFor(model=>item1.match_group_seq) </span> <span class="col_d"><a href="#">
<img src="../../Content/Images/delete-icon.png" width="17" height="17" border="0"
title="delete" /></a> </span><span class="col_e">@(item1.match_id)
</span><span class="col_f">
@Html.DropDownListFor(model => item1.match_loc, new SelectList((List<QIOnlineMVC3.Helpers.clsMatchLocations>)QIOnlineMVC3.Helpers.General.GetALLMatchLocations(), "MatchLocations", "MatchLocations", item1.match_loc))
</span><span class="col_g">
@Html.DropDownListFor(model => item1.match_target_field, new SelectList((List<QIOnlineMVC3.Helpers.clsTargetField>)QIOnlineMVC3.Helpers.General.GetALTargetField(), "TargetField", "TargetField", item1.match_target_field))
</span><span class="col_h">
@Html.DropDownListFor(model => item1.match_type, new SelectList((List<QIOnlineMVC3.Helpers.clsMatchType>)QIOnlineMVC3.Helpers.General.GetALLMatchType(), "MatchTypeID", "MatchType", item1.match_type))
</span><span class="col_i">
@Html.TextBoxFor(model => item1.match_set_name, new { @value = item1.match_set_name, @class="clsauto" })
@* <input type="text" name="sets" id="sets" class="clsauto" style="width:200px;" value='@(item1.match_set_name)'/>*@
</span>
</div>
</div>
}
<!-- end MATCH -->
<div class="new">
<a href="#">
<img src="../../Content/Images/new-icon.png" width="17" height="17" border="0" alt="New Match" />New
Match</a></div>
</div>
<!-- end MATCH GROUP -->
<!-- END Loop of Matches -->
<div class="new new_group">
<img alt="" src="../../Content/Images/new-icon.png" width="17" height="17" border="0" />@Ajax.ActionLink("New Group", "GetGroupMatch", new AjaxOptions{ UpdateTargetId = "divNewGroup", HttpMethod = "Get", InsertionMode = InsertionMode.InsertAfter})
<div class="delete_group">
Delete Group ID:
<input type="text" id='txtdeleteGroupNo_@(item.id)' />
<input type="submit" id='btnDeleteGroup_@(item.id)' value="Delete Group" class="btn btn_delete" style="float: none;" onclick="return DeleteGroup(this);" />
</div>
</div>
<div id="divNewGroup">
</div>
<div class="btn_row">
<input type="reset" name="reset" class="btn" value="Cancel" onclick='DoExpandCollapsh("trMinimised@(item.id)","main_collapsed@(item.id)","main_expanded@(item.id)")'/>
<input type="submit" name="btnSave" class="btn" value="Save" />
<a href="@(Url.Action("DeleteTravelAdsRule", new { id = item.id }))" class="btn btn_delete">
Delete Rule</a>
</div>
</div>
}
</td>
</tr>
}
</tbody>
Here is my Controller Actions
[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult _SaveGroupMatchs(FormCollection fc, TravelAdsRulesMatchsGroups trmg)
{
// trmg is null here... I am getting form collection but its comma separated, very annoying to deal with that.
}
Can anybody have Idea, how do I get Model values.
Here is my class information
Main class TravelAds – required to show mail records (grid)
TravelAdsRulesMatchsGroups – First foreach loop class inside the table
MatchCollection – Second foreach loop class inside TravelAdsRulesMatchsGroups
I am trying to get TravelAdsRulesMatchsGroups object with values and with sub class (Match Collection) in controller, there should be anyway, I think.
Thanks in Advance
– Amit Prajapati
Those
foreachloops that you wrote are killing everything. Please read about the standard conventions that you need to use for naming your input elements that the default model binder expects: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspxNow look at generated HTML source code of your page and more specifically the names of your input fields. What a mess, isn’t it? Nothing matches what the default model binder expects. When you use expressions such as
model => item1.match_typethe name of the generated input field doesn’t take into account the current navigational context of the complex property.One possibility is to use editor templates instead of those foreach loops. It’s the solution I recommend. I have written like gazillions of posts about them, just Google.
Another possibility is to modify your models to use indexed collections and then use
forloops instead offoreach:Notice how the lambda expressions used now includes not only the navigational property name but the index as well. This will allow for the helpers to generate proper names for the input fields.