ventajas - ¿Por qué ASP.NET MVC se preocupa por mis propiedades de solo lectura durante el enlace de datos?
modelo vista controlador pdf (6)
Edición: Se agregó una recompensa porque estoy buscando una solución MVC3 (si existe) que no sea esto:
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
Tengo una propiedad de solo lectura en mi modelo de ''CityStateZip''
Dirección'' ''CityStateZip''
.
Es solo una forma conveniente de obtener la ciudad, el estado, el código postal de una dirección de EE. UU. Emite una excepción si el país no es EE. UU. (Se supone que la persona que llama debe verificar primero).
public string CityStateZip
{
get
{
if (IsUSA == false)
{
throw new ApplicationException("CityStateZip not valid for international addresses!");
}
return (City + ", " + StateCd + " " + ZipOrPostal).Trim().Trim(new char[] {'',''});
}
}
Esto es parte de mi modelo por lo que se limita. Antes de ASP.NET MVC2 RC2, este campo nunca causaba problemas durante el enlace de datos. Nunca lo pensé realmente, después de todo, solo es de solo lectura.
Ahora, aunque con el lanzamiento de RC2 de enero de 2010, me da un error durante el enlace de datos: debido a que el modelo de enlace predeterminado parece querer verificar este valor (aunque sea de solo lectura).
Es la línea ''base.OnModelUpdated'' la que hace que se desencadene este error.
public class AddressModelBinder : DefaultModelBinder
{
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
base.OnModelUpdated(controllerContext, bindingContext);
Evidentemente, los cambios de última hora en el Modelbinder causaron este cambio en el comportamiento, pero aún no estoy seguro de cuáles son las repercusiones de esto, ¿o si esto es un error? Le estoy pasando esto al equipo de MVC, pero tengo curiosidad por saber si alguien más tiene alguna sugerencia sobre cómo puedo evitar que esta propiedad se enlace.
Vale la pena leer este artículo sobre los cambios, pero no menciona las propiedades de solo lectura (no es lo que yo esperaría). El problema (si hay uno) puede ser más amplio que esta situación; simplemente no estoy seguro acerca de ninguna discusión, ¡si es que hay alguna!
Validación de entrada frente a validación de modelo en ASP.NET MVC
Según lo solicitado por @haacked aquí está el stacktrace:
Obtengo esto simplemente agregando la siguiente línea a CUALQUIER modelo y haciendo una publicación al método de acción correspondiente. En este caso lo agregué a mi modelo más simple posible.
public string Foo { get { throw new Exception("bar"); } }
[TargetInvocationException: propiedad accessor ''Foo'' en el objeto ''Rolling_Razor_MVC.Models.ContactUsModel'' lanzó la siguiente excepción: ''bar''] System.ComponentModel.ReflectPropertyDescriptor.GetValue (componente del objeto) +390 System.Web.P. GetPropertyValueAccessor> b__a () +18 System.Web.Mvc.ModelMetadata.get_Model () +22 System.Web.Mvc.ModelMetadata.get_RealMators.png. .Linq. <SelectManyIterator> d__14`2.MoveNext () +273 System.Web.Mvc. <Validate> d__5.MoveNext () +644 System.Web.Mvc.Dv.Dv.DefaultModelBinder.OnModelUpdated (ControllerContext controllerCapac. .Web.Mvc.DefaultModelBinder.BindComplexElementalMazel (ControllerContext controllerContext, ModelBindingContext bindingContext, Modelo del objeto) +60 System.Web.Mv.C.C.Vc.p.p.C.P. trollerContext controllerContext, ModelBindingContext bindingContext) +280 System.Web.Mvc.Controller.TryUpdateModel (TModel prefijo, String [] includeProperties.pel.p.p.p.p.p.p.p.P.P.P.P.P.P.P.P.P.P.P.P. modelo) +73
¡TENGO EL MISMO PROBLEMA EXACTO!
Para obtener más información sobre mi problema, puede visitar ASP.NET MVC 2.0 ¿Propiedad de modelo no utilizada que se llama cuando se publica un producto en el servidor?
significa que debemos programar nuestras propiedades con el supuesto de que se llamarán de forma inesperada (antes de que las propiedades de las que depende se configuren / inicialicen, etc.) ... si es así, esto representa un cambio en nuestras prácticas de programación y lo haría Me gusta saber cómo proceder.
Mientras tanto, solo tengo un simple ''si'' para comprobar que soluciona el problema.
Creo que estoy experimentando un problema similar. He publicado los detalles:
http://forums.asp.net/t/1523362.aspx
edición : Respuesta del equipo MVC (de la URL anterior):
Investigamos esto y hemos llegado a la conclusión de que el sistema de validación se está comportando como se esperaba. Dado que la validación del modelo implica intentar ejecutar la validación en todas las propiedades, y como las propiedades de tipo de valor no anulables tienen un atributo [Requerido] implícito, estamos validando esta propiedad y llamando a su captador en el proceso. Entendemos que este es un cambio importante en V1 del producto, pero es necesario para que el nuevo sistema de validación del modelo funcione correctamente.
Tienes algunas opciones para solucionar esto. Cualquiera de estos debería funcionar:
- Cambie la propiedad Fecha a un método en lugar de una propiedad; De esta manera será ignorado por el framework MVC.
- ¿Cambiar el tipo de propiedad a DateTime? en lugar de DateTime. Esto elimina el [Requerido] implícito de esta propiedad.
- Borre el indicador DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes. Esto elimina el [Requerido] implícito de todas las propiedades de tipo de valor no anulables en toda la aplicación. Estamos considerando agregar en V3 del producto un atributo que nos indique "no lo vincules, no lo valides, simplemente fingimos que esta propiedad no existe".
Gracias de nuevo por el informe!
Estaba teniendo un problema similar, un campo que no esperaba que se validara estaba recibiendo un error cuando el formulario se envió al controlador. Después de buscar en Google, encontré http://codeblog.shawson.co.uk/mvc-strongly-typed-view-returns-a-null-model-on-post-back/ donde se señaló que los conflictos de nombres podían causar problemas.
Aunque no pensé que mi clase de variable post-back tuviera nombres de propiedad conflictivos, el cambio de nombre de la propiedad que recibió el error solucionó mi problema.
Esto se ve para todo el mundo como un error para mí. No entiendo por qué el ModelBinder necesita verificar mis propiedades de solo lectura (puede haber algunos aspectos técnicos, pero definitivamente no entiendo, y no estoy dispuesto a pasar el tiempo intentando).
Agregué el siguiente proveedor de metadatos de modelo a mi solución para solucionar el problema
protected override CachedDataAnnotationsModelMetadata CreateMetadataPrototype(IEnumerable<Attribute> attributes, Type containerType, Type modelType, string propertyName)
{
var metadata = base.CreateMetadataPrototype(attributes, containerType, modelType, propertyName);
if (metadata.IsReadOnly)
{
metadata.IsRequired = false;
}
return metadata;
}
protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor)
{
var metadata = base.CreateMetadataFromPrototype(prototype, modelAccessor);
if (prototype.IsReadOnly)
{
metadata.IsRequired = false;
}
return metadata;
}
También deberá agregar lo siguiente a Global.asax.cs
protected void Application_Start()
{
ModelMetadataProviders.Current = new RESModelMetadataProvider();
ModelBinders.Binders.Add(typeof(SmartDate), new SmartDateModelBinder());
...
}
Por supuesto, supongo que podría convertir CityStateZip
en GetCityStateZip()
pero luego no puedo GetCityStateZip()
en algo como Silverlight con la misma facilidad. Esto podría funcionar para una solución temporal para cualquier otra persona que experimente este problema.
Sigo teniendo el mismo problema con MVC3.
Creo que la mejor manera es solo para esto en global.asax (de la respuesta de SevenCentral):
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
Esto se deshabilitará para todos ellos.