Pregunta

estoy rascándome la cabeza un poco en cómo enlazadores de modelos hacen su trabajo en ASP.Net MVC.

Para ser más específicos, el método bindModel () tiene un parámetro ModelBindingContext que contiene el nombre del modelo y tipo, pero no entiendo cómo el ModelBindingContext recibe estos valores.

Un modelo MVC tiene que ser poblada de los valores publicados de forma o parámetros de cadena de consulta, u otras fuentes de datos. Pero qué mecanismo determina el tipo de modelo entregado a la ModelBindingContext, y cómo es un tipo de modelo elegido sobre otro tipo de modelo, más aún (por ejemplo) una simple lista que contiene los valores individuales enviados?

Simplemente me parece que la ModelBindingContext "sabe" el tipo de modelo que está siendo entregado, y no estoy seguro de que eso es viniendo desde o el flujo de trabajo involucrados en poblarlo.

¿Fue útil?

Solución

Es una pregunta interesante. Aquí está una descripción sencilla de lo que hace MVC. Todo está a cargo de la clase ControllerActionInovker. Este no es el fin específico, pero está cerca.

  1. ControllerActionInovker determina el tipo de parámetro a través de la reflexión.
  2. Siguiente ValueProviders se crean a partir de la solicitud HttpContext forma, la vía, cadena de consulta, etc. propiedades. También puede proporcionar a sus propios proveedores de valor.
  3. Estos ValueProviders se suministran a un ModelBindingContext a través de una colección que actúa como un ValueProvider virtual.
  4. A continuación, ControllerActionInovker busca una ModelBinder para el tipo específico. Si no encuentra uno el valor predeterminado es el construido en DefaultModelBinder.
  5. En la mayoría de los casos se utiliza el DefaultModelBinder. trabajo que es es crear un modelo, y el uso de los ValueProviders para conectar las propiedades con valores utilizando los nombres del modelo como clave. Cuando los ValueProviders tienen un valor, que devolver un objeto ValueProviderResult que es responsable de la conversión de tipos.

Se puede ver esto por sí mismo en el href="http://aspnet.codeplex.com/releases/view/41742" rel="noreferrer"> fuente . Look para la clase y el método ControllerActionInvoker getParameterValue.

Otros consejos

El ModelBindingContext "sabe" el tipo de modelo que está siendo entregado porque hay que o bien:

  • Añadir un atributo ModelBinder a su modelo
  • Registro del ModelBinder con el modelo mediante el método ModelBinders.Binders.Add ().

Ejemplo de atributo ModelBinder:

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

Ejemplo de ModelBinders.Binders.Add ():

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

Si ha registrado su ModelBinder y ha implementado el método bindModel:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ... }
  1. Consulta el ModelBindingContext.ModelType es igual a su modelo, por ejemplo,

    if (bindingContext.ModelType == typeof(Contact)) { ... }
    
  2. rehidratar el modelo de la propiedad ModelBindingContext.ValueProvider para recuperar instancias ValueProviderResult que representan los datos de los puestos de formulario, los datos de ruta, y la cadena de consulta por ejemplo.

    bindingContext.ValueProvider["Name"].AttemptedValue;
    

Se utilizaron los siguientes libros ASP.NET MVC 2 en Acción y ASP.NET MVC 1.0 rápidamente

La forma en que lo veo es que ControllerActionInvoker utiliza la reflexión para obtener el tipo de parámetro, entonces se comprueba si cualquier ModelBinder se asigna para hacer frente a ese tipo, si lo que crea la instancia de este ModelBinder y lo pasa BindingContext que contendrá la (modelo objeto, nombre del modelo, tipo de modelo, filtro de propiedades) para ese objeto tipo de parámetro y una colección proveedor de valor (ModelBindingContext.ValueProvider) de todos los demás proveedores de valor (Form, cadena de consulta etc.), actuando como un proveedor de gran valor virtual.

El ModelBinder entonces sí utiliza la reflexión para obtener todos los nombres de propiedades para el tipo asignado a su aprieto y se ejecuta de forma recursiva en sí en contra de todos los proveedores de valor en (ModelBindingContext.ValueProvider) y busca los nombres de propiedad en los proveedores de valor, la unión de esos valores para los cuales los nombres (tomadas de cliente) coinciden con los nombres de las propiedades de tipo, cuando coinciden el valor vuelve proveedor de un objeto ValueProviderResult, que lleva el nombre y el valor de la propiedad correspondiente en el modelo.

scroll top