How to chain binders in asp.net MVC 4?



我刚刚用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个大的自定义模型活页夹。

相关内容

  • 没有找到相关文章

最新更新