【问题标题】:ASP.Net MVC ModelBindingContext class-- how are its model values populated?ASP.Net MVC ModelBindingContext 类——它的模型值是如何填充的?
【发布时间】:2011-04-01 05:25:43
【问题描述】:

我对模型绑定器如何在 ASP.Net MVC 中工作感到有些摸不着头脑。

具体来说,BindModel() 方法有一个 ModelBindingContext 参数,其中保存了模型名称和类型,但是我不明白 ModelBindingContext 是如何接收这些值的。

必须从发布的表单值或查询字符串参数或其他数据源填充 MVC 模型。但是什么机制决定了传递给 ModelBindingContext 的模型类型,以及如何选择一种模型类型而不是另一种模型类型,甚至(比如说)一个包含各个发布值的简单列表?

在我看来,ModelBindingContext“知道”它正在处理的模型类型,我不确定它来自哪里或填充它所涉及的工作流。

【问题讨论】:

  • 天哪,对不起,我标记为关闭错误的问题

标签: asp.net-mvc modelbinders custom-model-binder


【解决方案1】:

有趣的问题。以下是 MVC 功能的简单概述。这一切都由 ControllerActionInovker 类处理。这没有特定的顺序,但很接近。

  1. ControllerActionInovker 通过反射确定参数类型。
  2. 下一个 ValueProviders 是从 HttpContext Request Form、Route、QueryString 等属性创建的。您还可以提供自己的价值提供者。
  3. 这些 ValueProviders 通过充当虚拟 ValueProvider 的集合提供给 ModelBindingContext。
  4. 然后 ControllerActionInovker 查找特定类型的 ModelBinder。如果找不到,则默认使用内置的 DefaultModelBinder。
  5. 在大多数情况下使用 DefaultModelBinder。它的工作是创建一个模型,并使用 ValueProviders 使用模型属性名称作为键将属性与值连接起来。当 ValueProviders 有值时,它们返回一个负责类型转换的 ValueProviderResult 对象。

您可以在ASP.net MVC source located at codeplex.com 中亲自查看。查找 ControllerActionInvoker 类和 GetParameterValue 方法。

【讨论】:

    【解决方案2】:

    ModelBindingContext“知道”它正在处理的模型类型,因为您必须:

    • 为您的模型添加 ModelBinder 属性
    • 使用 ModelBinders.Binders.Add() 方法将 ModelBinder 注册到您的模型。

    ModelBinder 属性示例:

    [ModelBinder(typeof(ContactBinder))]
    public class Contact { ... }
    

    ModelBinders.Binders.Add() 示例:

    void Application_Start()
    {
      ModelBinders.Binders[typeof(Contact)] = new ContactBinder();
    }
    

    如果您已经注册了 ModelBinder 并实现了 BindModel 方法:

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ... }
    
    1. 查询 ModelBindingContext.ModelType 是否等于您的模型,例如

      if (bindingContext.ModelType == typeof(Contact)) { ... }
      
    2. 从 ModelBindingContext.ValueProvider 属性中重新水化您的模型,以检索 ValueProviderResult 实例,这些实例代表来自表单帖子、路由数据和查询字符串的数据,例如

      bindingContext.ValueProvider["Name"].AttemptedValue;
      

    使用了以下书籍 ASP.NET MVC 2 实战ASP.NET MVC 1.0 快速

    【讨论】:

    • 谢谢。我仍然对获取和读取发布的表单信息的代码感到困惑,确定它是一个联系人,然后将其传递给 ContactBuinder 类中的 ModelBindingContext 对象。
    【解决方案3】:

    我看到它的方式是 ControllerActionInvoker 使用反射来获取参数类型,然后检查是否分配了任何 ModelBinder 来处理该类型,如果是,则实例化此 ModelBinder 并将其传递给它将包含(模型该参数类型对象的对象、模型名称、模型类型、属性过滤器)和所有其他值提供者(表单、查询字符串等)的值提供者集合 (ModelBindingContext.ValueProvider),充当一个大型虚拟值提供者。

    然后,ModelBinder 本身使用反射来获取分配给其绑定的类型的所有属性名称,并针对 (ModelBindingContext.ValueProvider) 中的所有值提供者递归运行自身,并在这些值提供者中查找属性名称,绑定这些值名称(取自客户端)与类型属性名称匹配的对象,当它们匹配时,值提供者返回一个 ValueProviderResult 对象,其中包含模型上相应属性的名称和值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多