Why doesn't the default model binder update my partial view model on postback?
- by bdnewbe
I have a class that contains another class as one of its properties.
public class SiteProperties
{
public SiteProperties()
{
DropFontFamily = "Arial, Helvetica, Sans-serif";
}
public string DropFontFamily { get; set; }
private ResultPageProperties m_ResultPagePropertyList;
public ResultPageProperties ResultPagePropertyList
{
get
{
if (m_ResultPagePropertyList == null)
m_ResultPagePropertyList = new ResultPageProperties();
return m_ResultPagePropertyList;
}
set { m_ResultPagePropertyList = value; }
}
}
The second class has just one property
public class ResultPageProperties
{
public ResultPageProperties()
{
ResultFontFamily = "Arial, Helvetica, Sans-serif";
}
public string ResultFontFamily { get; set; }
}
My controller just grabs the SiteProperties and returns the view. On submit, it accepts SiteProperties and returns the same view.
public class CompanyController : Controller
{
public ActionResult SiteOptions(int id)
{
SiteProperties site = new SiteProperties();
PopulateProperyDropDownLists();
return View("SiteOptions", site);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SiteOptions(SiteProperties properties)
{
PopulateProperyDropDownLists();
return View("SiteOptions", properties);
}
private void PopulateProperyDropDownLists()
{
var fontFamilyList = new List<SelectListItem>();
fontFamilyList.Add(new SelectListItem() { Text = "Arial, Helvetica, Sans-serif", Value = "Arial, Helvetica, Sans-serif" });
fontFamilyList.Add(new SelectListItem() { Text = "Times New Roman, Times, serif", Value = "Times New Roman, Times, serif" });
fontFamilyList.Add(new SelectListItem() { Text = "Courier New, Courier, Monospace", Value = "Courier New, Courier, Monospace" });
ViewData["FontFamilyList"] = fontFamilyList;
}
}
The view contains a partial view that renders the ResultPageProperties Model.
<% using (Html.BeginForm("SiteOptions", "Company", FormMethod.Post))
{%>
<p><input type="submit" value="Submit" /></p>
<div>View level input</div>
<div>
<label>Font family</label><br />
<%= Html.DropDownListFor(m => m.DropFontFamily, ViewData["FontFamilyList"] as List<SelectListItem>, new { Class = "UpdatesDropDownExample" })%>
</div>
<% Html.RenderPartial("ResultPagePropertyInput", Model.ResultPagePropertyList); %>
<% } %>
The partial is just
<div style='margin-top: 1em;'>View level input</div>
<div>
<label>Font family</label><br />
<%= Html.DropDownListFor(m => m.ResultFontFamily, ViewData["FontFamilyList"] as List<SelectListItem>, new { Class = "UpdatesResultPageExample" })%>
</div>
OK, so when the page renders, you get "Arial, ..." in both selects. If you choose another option for both and click submit, the binder populates the SiteProperties object and passes it to the controller. However, the ResultFontFamily always contains the original value. I was expecting it to have the value the user selected.
What am I missing?