ASP.Net MVC ModelBindingContext 类——如何填充其模型值?

发布于 2024-09-15 11:57:44 字数 337 浏览 13 评论 0原文

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

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

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

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

I'm scratching my head a bit at how model binders do their work in ASP.Net MVC.

To be specific, the BindModel() method has a ModelBindingContext parameter that holds the model name and type, but I don't understand how the ModelBindingContext receives these values.

An MVC model has to be populated from posted form values or query string parameters, or other sources of data. But what mechanism determines the model type handed to the ModelBindingContext, and how is one model type chosen over another model type, over even (say) a simple list containing the individual posted values?

It just appears to me the ModelBindingContext "knows" the type of model it's being handed, and I'm not sure where that's coming from or the workflow involved in populating it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

逆夏时光 2024-09-22 11:57:44

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

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

您可以在 位于 codeplex.com 的 ASP.net MVC 源代码中亲自查看这一点。查找 ControllerActionInvoker 类和 GetParameterValue 方法。

Interesting question. Here is a simple overview of what MVC does. It's all handled by the ControllerActionInovker class. This is not in specific order, but is close.

  1. ControllerActionInovker determines the parameter type via reflection.
  2. Next ValueProviders are created from the HttpContext Request Form, Route, QueryString, etc. properties. You can also provide your own value providers.
  3. These ValueProviders are supplied to a ModelBindingContext via a collection that acts as a virtual ValueProvider.
  4. Then ControllerActionInovker looks for a ModelBinder for the specific type. If it doesn't find one it defaults to the built in DefaultModelBinder.
  5. In most cases the DefaultModelBinder is used. It's job is to create a Model, and use the ValueProviders to connect the properties with values using the model properties names as a key. When the ValueProviders have a value, they return a ValueProviderResult object that is responsible for type conversion.

You can see this for yourself in the ASP.net MVC source located at codeplex.com. Look for the ControllerActionInvoker class and the GetParameterValue method.

む无字情书 2024-09-22 11:57:44

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. < p>查询 ModelBindingContext.ModelType 是否等于您的模型,例如

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

    bindingContext.ValueProvider["名称"].AttemptedValue;
    

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

The ModelBindingContext "knows" the type of model it's being handed because you have to either:

  • Add a ModelBinder attribute to your model
  • Register the ModelBinder with your model using the ModelBinders.Binders.Add() method.

Example of ModelBinder attribute:

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

Example of ModelBinders.Binders.Add():

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

If you have registered your ModelBinder and have implemented the BindModel method:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ... }
  1. Query the ModelBindingContext.ModelType is equal to your Model e.g.

    if (bindingContext.ModelType == typeof(Contact)) { ... }
    
  2. Rehydrate your model from the ModelBindingContext.ValueProvider property to retrieve ValueProviderResult instances that represent the data from form posts, route data, and the query string e.g.

    bindingContext.ValueProvider["Name"].AttemptedValue;
    

The following books were used
ASP.NET MVC 2 in Action and
ASP.NET MVC 1.0 Quickly

一指流沙 2024-09-22 11:57:44

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

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

The way I see it is that ControllerActionInvoker uses reflection to get the parameter type, it then checks if any ModelBinder is assigned to deal with that type, if so it instantiates this ModelBinder and passes it the BindingContext which will contain the (model object, model name, model type, property filter) for that parameter type object and a value provider collection (ModelBindingContext.ValueProvider) of all other value providers (Form, Query String etc.), acting as one big virtual value provider.

The ModelBinder then itself uses reflection to get all property names for the type its assigned to bind and runs itself recursively against all the value providers in (ModelBindingContext.ValueProvider) and looks for the property names in those value providers, binding those values for whom the names (taken from client) match the type property names, when they match the value provider returns a ValueProviderResult object, bearing the name and value for the respective property on the model.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文