简体   繁体   English

如何在asp.net MVC 4中链接活页夹?

[英]How to chain binders in asp.net MVC 4?

I just wrote my first model binder in asp.net MVC. 我刚刚在asp.net MVC中编写了我的第一个模型活页夹。 I started with a pure HTML form that had all the inputs with names prefixed by "fm_". 我从纯HTML表单开始,该表单的所有输入均以“ 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? 有没有一种方法可以实现,从而避免我必须解析DateTime并获取默认的资料夹来替我做到这一点?

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

You can extend the DefaultModelBinder rather than implementing IModelBinder. 您可以扩展DefaultModelBinder而不是实现IModelBinder。

Here's an example for 这是一个例子

    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
        }
    }

However if we consider a more realistic scenario where your HuggiesModel is comprised of complex types plus simple types (like what you have now), you'd use the Default Model binding with the simple types (Together with naming conventions - ie having FirstName property instead of fm_firstname). 但是,如果我们考虑更现实的情况,即您的HuggiesModel由复杂类型加简单类型组成(如您现在所拥有的),则可以将Default Model绑定与简单类型一起使用(与命名约定一起使用-即拥有FirstName属性)的fm_firstname)。 For complex types you'd implement a custom model binder for each type. 对于复杂类型,您将为每种类型实现自定义模型绑定程序。 You don't necessarily need to have 1 large custom model binder for 'HuggiesModel'. 您不一定需要为“ HuggiesModel”使用1个大型自定义模型活页夹。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM