我刚刚用asp.net MVC编写了我的第一个模型绑定器。我从一个纯HTML表单开始,它的所有输入都以"fm_"为前缀。
public class HuggiesModel
{
public string fm_firstname { get; set; }
public DateTime fm_duedate { get; set; }
}
默认的活页夹工作得很好,我认为这是一个很好的时间节省。
然后我决定我想要更干净的房产名称,所以我改为:
[ModelBinder(typeof(HuggiesModelBinder))]
public class HuggiesModel
{
public string FirstName { get; set; }
public DateTime? DueDate { get; set; }
}
和模型绑定器:
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];
}
}
有没有一种方法可以让我实现这一点,从而避免解析DateTime并让默认的绑定器为我做这件事?
备注:
我意识到我可以更改表单输入名称以匹配我想要的模型名称,但我故意不这样做是为了获得编写模型活页夹的经验,这让我产生了这个问题。
这个问题的标题是基于我试图做的事情的概念——创建一个看起来像的链
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
您可以扩展DefaultModelBinder,而不是实现IModelBinder。
下面是的一个例子
public class HuggiesModelBinder:DefaultModelBinder
{
protected override void BindProperty( ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor )
{
if (propertyDescriptor.PropertyType == typeof(DateTime))
{
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
// bind the rest of the properties here
}
}
但是,如果我们考虑一个更现实的场景,即您的HuggiesModel由复杂类型和简单类型组成(如您现在所拥有的),则您将使用Default Model与简单类型的绑定(以及命名约定,即具有FirstName属性而非fm_FirstName)。对于复杂的类型,您可以为每种类型实现一个自定义模型绑定器。"HuggiesModel"不一定需要1个大的自定义模型活页夹。