25

有人可以告诉我在 global.asax 中使用[ModelBinder()]属性与注册模型绑定器的优缺点ModelBinders.Add()吗?

我能想到的一个优点是它更明确,而在全局中注册ModelBinders对于检查操作方法的人来说并不那么明显。

我能想到的一个权衡是它不可重用,因为您必须将此属性添加到需要使用此模型绑定器的所有操作方法中,而在全局中注册ModelBinders将使其可用于接收该模型的所有操作方法。

这是唯一的区别吗?

换句话说,说明这是正确的:

  • 如果您只在一种操作方法中使用模型(可能是两种,get + post),那么使用[ModelBinder()].
  • 如果您在多个操作方法中使用模型,则将其注册到全局ModelBinders.
4

2 回答 2

33

这些技术的结果将是相同的,因此主要取决于团队感觉更舒服的问题。所以你可以想出一个像你所说的那样的约定。

就个人而言,我更喜欢不必为使用该模型的每个操作方法设置属性。所以我会选择以下选项之一:

  • 在模型类上设置属性,如:

    [ModelBinder(typeof(MyModelBinder))]
    public class MyModel
    {
        ...
    }    
    
  • 全局注册活页夹

    ModelBinders.Binders.Add(typeof(MyModel), new MyModelBinder())
    

我更喜欢其中一个的另一个原因是,如果您必须手动触发模型绑定过程,您可能还希望使用自定义模型绑定器:

public ActionResult SomeActionMethod()
{
     MyModel model = ...

     //manually invoke the model binding process considering only query string data
     //The custom model binder will be used only if it was globally registered
     //in the binders dictionary or set in an attribute of the model class
     TryUpdateModel(model, new QueryStringValueProvider())

     ...
}

IModelBinderProvider您还可以选择通过实现接口并在 global.asax 中注册来实现自己的逻辑来选择模型绑定器,如

ModelBinderProviders.BinderProviders.Add(new CustomModelBinderProvider()) 

在方法参数中使用属性的一种方法可以是为该特定方法覆盖原本会使用的模型绑定器。因此,您可以为您的类全局注册一个模型绑定器,并使用该属性在一个特定的操作方法中覆盖它。

最后,有很多选择模型活页夹的选项。在 asp MVC 3 中,这将通过以下方式解决(假设您使用的是默认的 ControllerActionInvoker)

  1. 动作参数的属性。请参阅ControllerActionInvoker 类的 GetParameterValue 方法

  2. 从 IModelBinderProvider 返回的 Binder。请参阅ModelBinderDictionary 类中的 GetBinder 方法

  3. 在 ModelBinders.Binders 字典中全局注册的 Binder。

  4. [ModelBinder()]在模型类型的属性中定义的 Binder 。

  5. DefaultModelBinder。

于 2012-12-06T17:27:08.613 回答
1

在我看来,使用属性而不是添加到 Global.asax 中的模型绑定器集合的优势在于,您可以告诉方法(或类)使用哪个特定绑定器,而不是将绑定器与特定类型相关联。然后您可以基于上下文而不是类型创建模型。

于 2014-09-09T15:46:27.817 回答