【问题标题】:Using ModelBinder attribute vs. ModelBinders.Add()使用 ModelBinder 属性与 ModelBinders.Add()
【发布时间】:2023-03-17 20:08:01
【问题描述】:

谁能告诉我在 global.asax 中使用 [ModelBinder()] 属性与通过 ModelBinders.Add() 注册模型绑定器的优点/缺点?

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

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

这是唯一的区别吗?

换句话说,这样说是否正确:

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

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


    【解决方案1】:

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

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

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

      [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 class的GetParameterValue方法

    2. 从 IModelBinderProvider 返回的 Binder。参见ModelBinderDictionary class中的GetBinder方法

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

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

    5. DefaultModelBinder。

    【讨论】:

    • 您可以设置 DefaultModelBinder - 方便调试ModelBinders.Binders.DefaultBinder = new TestBinder();
    【解决方案2】:

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

    【讨论】:

    • 属性也是我的首选方法。它允许保持模型更加抽象(甚至存储在单独的程序集中),将绑定机制留在控制器基础架构级别。模型不应该太在意它的使用方式和位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    相关资源
    最近更新 更多