I just wrote my first model binder in asp.net MVC. I started with a pure HTML form that had all the inputs with names prefixed by "fm_".
public class HuggiesModel
{
public string fm_firstname { get; set; }
public DateTime fm_duedate { get; set; }
}
The default binder worked fine which I saw as a nice time saver.
Then I decided I wanted cleaner property names so I changed to:
[ModelBinder(typeof(HuggiesModelBinder))]
public class HuggiesModel
{
public string FirstName { get; set; }
public DateTime? DueDate { get; set; }
}
And the model binder:
public class HuggiesModelBinder : IModelBinder
{
private HttpRequestBase request;
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException("bindingContext");
this.request = controllerContext.HttpContext.Request;
var model = new HuggiesModel
{
FirstName = GetQueryStringValue("fm_firstname"),
};
string dateTimeString = GetQueryStringValue("fm_duedate");
model.DueDate = string.IsNullOrWhiteSpace(dateTimeString)
? default(DateTime?)
: DateTime.Parse(dateTimeString);
return model;
}
private string GetQueryStringValue(string key)
{
if (this.request.HttpMethod.ToUpper() == "POST")
return this.request.Form[key];
return this.request.QueryString[key];
}
}
Is there a way I could have implemented this such that I avoid having to parse the DateTime and get the default binder to do that for me?
Notes:
I realize I could just change the form input names to match the model names I desire but I purposely didn't do that to gain experience writing a model binder and that led me to this question.
The title of the question is based on the conceptual idea of what I'm trying to do - create a chain that looks like:
request
-> default model binder binds get/post data to first view model
-> my model binder binds first view model to second view model
-> controller action method is called with second view model