Html.EditorFor not updating model on post
- by Dave
I have a complex type composed of two nullable DateTimes:
public class Period
{
public DateTime? Start { get; set; }
public DateTime? End { get; set; }
public static implicit operator string(Period period) { /* converts from Period to string */ }
public static implicit operator Period(string value) { /* and back again */ }
}
I want to display them together in a single textbox as a date range so I can provide a nice jQuery UI date range selector. To make that happen have the following custom editor template:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Period>" %>
<% string name = ViewData.TemplateInfo.HtmlFieldPrefix; %>
<%= Html.PeriodTextBox(name, Model.EarliestDate, Model.LatestDate) %>
Where Html.PeriodTextBox is an extension method I've written that just concatenates the two dates sensibly, turns off autocomplete and generates a textbox, like so:
public static MvcHelperString PeriodTextBox(this HtmlHelper helper, string name, DateTime? startDate, DateTime? endDate)
{
TagBuilder builder = new TagBuilder("input");
builder.GenerateId(name);
builder.Attributes.Add("name", name);
builder.Attributes.Add("type", "text");
builder.Attributes.Add("autocomplete", "off");
builder.Attributes.Add("value", ConcatDates(startDate, endDate));
return MvcHtmlString.Create(builder.ToString());
}
That's working fine in that I can call <%= Html.EditorFor(m => m.ReportPeriod) %> and I get my textbox, then when the form is submitted the FormCollection passed to the post action will contain an entry named ReportPeriod with the correct value.
[HttpPost]
public ActionResult ReportByRange(FormCollection formValues)
{
Period reportPeriod = formValues["ReportPeriod"]; // creates a Period, with the expected values
}
The problem is if I replace the FormCollection with the model type I'm passing to the view then the ReportPeriod property never gets set.
[HttpPost]
public ActionResult ReportByRange(ReportViewModel viewModel)
{
Period reportPeriod = viewModel.ReportPeriod; // this is null
}
I expected MVC would try to set the string from the textbox to that property and it would automatically generate a Period (as in my FormCollection example), but it's not.
How do I tell the textbox I've generated in the custom editor to poplate that property on the model?