2011-12-19 9 views
5

Estoy usando ASP.NET MVC3 y me pregunto si el modelbinder predeterminado enlaza a propiedades públicas pero no a campos públicos.¿Hay algún motivo por el que el enlazador de modelos predeterminado no se una a los campos?

Normalmente solo defino las clases de modelo con propiedades, pero a veces uso algunas clases predefinidas que contienen algunos campos. Y cada vez que tengo que depurar y recordar que al encuadernador simplemente no le gustan los campos.

La pregunta: ¿Cuál es la razón detrás de esto?

Respuesta

0

Quizás el motivo por el que se ignoran los campos es para aumentar el rendimiento del encuadernador. En lugar de buscar todos los campos y propiedades. La Carpeta de modelo busca solo propiedades.

Aunque creo que el Binder de Modelos usa el caché para mejorar el rendimiento.

2

pero a veces yo uso algunas clases predefinidas que contiene algunos campos

Aunque no puedo responder a su pregunta sobre la razón exacta por la que el ligante modelo por defecto funciona sólo con propiedades (mi suposición es que se respeta mejor encapsulado de esta manera y evita modificar el estado interno del objeto, que es lo que representan los campos) Puedo decir que lo que usted llama clases predefinidas normalmente deberían ser modelos de vista. Siempre debe usar modelos de vista hacia y desde las acciones de su controlador. Esos modelos de vista son clases que se definen específicamente para cumplir los requisitos de la vista dada.

Volviendo al punto principal: se supone que los campos solo se modifican dentro de la clase dada. No se debe acceder directamente desde el exterior. Ellos representan y mantienen el estado interno de la clase. Por otro lado, las propiedades son lo que debería estar expuesto al mundo exterior. Imagina que en el getter/setter de propiedades tenías algo de lógica personalizada. Al modificar directamente el campo, esta lógica personalizada se rompería y podría llevar al objeto a un estado incoherente.

+1

Ok, pero para eso tienes los modificadores de acceso. Si no quiero que se establezca un campo directamente, simplemente lo declaro 'privado '. Las clases de Viewmodel normalmente son solo contenedores de datos y, en su mayoría, no contienen mucha lógica, así que pensé que podría estar bien usar campos públicos. – Jan

+0

@ Jan, normalmente los campos deben ser privados. –

+1

Y normalmente no debería tener lógica en los captadores de propiedades ... – gdoron

0

DefaultModelBinder expone un método público: DefaultModelBinder.BindModel, y una cantidad de métodos protegidos disponibles para sobrescribir. Todos ellos enumerados here.

Además del modelo, estos métodos se refieren a propiedades solamente, no campos, como

  • GetModelProperties,
  • GetFilteredModelProperties,
  • getPropertyValue,
  • OnXYZValidating,
  • OnXYZValidated,
  • OnXYZUpdating,
  • OnXYZUpdated,
  • GetXYZValue,

donde XYZ representa ya sea Model, o Property/ies, o ambos, y así sucesivamente.

Como puede ver, no hay ningún Fields mencionado con estos nombres de ningún tipo. Como se explicó en Darin, el cuaderno no tolera ningún cambio directo en el estado del modelo. Por lo tanto, no Field en sus métodos.

Y también, es posible que desee echar un vistazo a otra clase importante: ModelBindingContext. Una instancia de esta clase se pasa al BindModel, y luego a BindSimpleModel, y BindComplexModel, dependiendo del tipo de modelo (string, int, ... se consideran simples, todo lo demás es complejo).

Así, este marco tiene las siguientes propiedades:

  • ModelXYZ y
  • PropertyXYZ.

En otras palabras, no tiene medios para hacer referencia a los campos en su ViewModel a menos que no anule estas clases y tome medidas especiales para hacerlo.

Pero, una vez más, tenga cuidado con la lucha contra el marco, siempre es más fácil seguirlo en su lugar.

EDIT: La clase ModelMetadata contiene todos los datos necesarios para vincular el modelo. Sin embargo, su código no muestra ningún signo de campos, nombres de campos, etc. Solo se hace referencia a las propiedades y se accede a ellas. Por lo tanto, incluso si intenta heredar y anular DefaultModelBinder y ModelBinderContext, todavía no podrá acceder a la fiellds, no importa cuál sea su modificador de acceso es: pública, privada, etc.

Hope esto explica la mayor parte de ella.

Cuestiones relacionadas