1

我刚刚在 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
4

1 回答 1

1

您可以扩展 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 由复杂类型和简单类型组成(就像您现在拥有的那样),您将使用带有简单类型的默认模型绑定(连同命名约定 - 即具有 FirstName 属性fm_firstname)。对于复杂类型,您将为每种类型实现一个自定义模型绑定器。您不一定需要 1 个用于“HuggiesModel”的大型自定义模型绑定器。

于 2013-02-21T06:34:23.213 回答