¿Por qué ASP.NET MVC atención acerca de mis propiedades de solo lectura durante el enlace de datos?

StackOverflow https://stackoverflow.com/questions/2211829

Pregunta

Editar:Añadido recompensa porque estoy buscando un MVC3 solución (si existe) es otro que este:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValuetypes = false;


Tengo una propiedad de sólo lectura en mi 'Dirección' modelo 'CityStateZip'.

Es sólo una manera conveniente de obtener de la ciudad, estado, código postal de una dirección en los estados unidos.Se lanza una excepción si el país no se USA (la persona que llama se supone comprobar, en primer lugar).

    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 hace obligado.Antes de ASP.NET MVC2 RC2 este campo no se había causado un problema en el enlace de datos.Nunca he pensado realmente acerca de él - después de todo solo es de sólo lectura.

Ahora, aunque con la de enero de 2010 versión RC2 me da un error en el enlace de datos - porque el modelo predeterminado cuaderno parece que quiere comprobar este valor (aunque sea de sólo lectura).

Es la 'base.OnModelUpdated' línea que hace que este error se dispara.

public class AddressModelBinder : DefaultModelBinder
{
    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        base.OnModelUpdated(controllerContext, bindingContext);

En los últimos minutos de cambios en el modelbinder evidentemente causado este cambio en el comportamiento, pero no estoy muy seguro todavía de lo que el repurcussions de ella - o si es o no es un bug?Estoy pasando esta en el MVC equipo pero la curiosidad de saber si alguien tiene alguna sugerencia en el mientras tanto, ¿cómo puedo evitar que esta propiedad de la unión.

Este artículo es bien vale la pena leer acerca de los cambios - pero no menciona readonly propiedades en todo (no es que yo se lo espera).El problema (si lo hay) puede ser más amplio que esta situación - no estoy seguro acerca de cualquier repurcussions - si!

Validación de entrada vsLa Validación del modelo en ASP.NET MVC


Según lo solicitado por @haacked aquí está el stacktrace :

Me sale esto, simplemente añadiendo la siguiente línea a CUALQUIER modelo y hacer un post para el correspondiente método de acción.En este caso he añadido a mi más simple posible modelo.

 public string Foo { get { throw new Exception("bar"); } }

[TargetInvocationException:Descriptor de acceso de propiedad 'Foo' el objeto 'Rolling_Razor_MVC.Modelos.ContactUsModel' lanzó la siguiente excepción:'bar'] Sistema.ComponentModel.ReflectPropertyDescriptor.GetValue(Objeto componente) +390 Sistema.Web.Mvc.<>c__DisplayClassb.<GetPropertyValueAccessor>b__a() +18 Sistema.Web.Mvc.ModelMetadata.get_Model() +22 Sistema.Web.Mvc.ModelMetadata.get_RealModelType() +29 Sistema.Web.Mvc.<GetValidatorsImpl>d__0.MoveNext() +38 Sistema.Linq.<SelectManyIterator>d__14`2.MoveNext() +273 Sistema.Web.Mvc.<Validate>d__5.MoveNext() +644 Sistema.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +92 Sistema.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, modelo de Objetos) +60 Sistema.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1048 Sistema.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +280 Sistema.Web.Mvc.El controlador.TryUpdateModel(TModel modelo, Cadena de prefijo, String[] includeProperties, String[] excludeProperties, IValueProvider valueProvider) +449 Sistema.Web.Mvc.El controlador.TryUpdateModel(TModel modelo) +73

¿Fue útil?

Solución

Creo que estoy experimentando un problema similar.He publicado los detalles:

http://forums.asp.net/t/1523362.aspx


editar:Respuesta de MVC equipo (desde la URL de arriba):

Hemos investigado esto y han concluido que el sistema de validación que se está comportando como se esperaba.Desde la validación del modelo consiste en tratar de ejecutar la validación sobre todas las propiedades, y ya no los aceptan tipo de valor de las propiedades tienen implícito un atributo [Requerido], estamos validando esta propiedad y llamando a su getter en el proceso.Entendemos que este es un cambio de hora desde la V1 del producto, pero es necesario para hacer que el nuevo modelo de sistema de validación de funcionar correctamente.

Usted tiene un par de opciones para solucionar este problema.Uno de estos debería funcionar:

  • Cambiar la Fecha de la propiedad a un método en lugar de una propiedad;de esta manera será ignorado por el marco de MVC.
  • Cambiar el tipo de propiedad a DateTime?en lugar de DateTime.Esto elimina el implícito [Requerido] a partir de esta propiedad.
  • Claro que la estática DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValuetypes bandera.Esto elimina el implícito [Requerido] de todos los que no aceptan valores null valor de propiedades de tipo en toda la aplicación.Estamos pensando en añadir en la V3 el producto de un atributo que será señal de que nos "no se unen, no validar, sólo pretendo que esta propiedad no existe."

Gracias de nuevo por el informe!

Otros consejos

Sigue teniendo el mismo problema con MVC3.

Creo que la mejor manera es sólo para este mundial.asax (de SevenCentral la respuesta):

 DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

Esto deshabilitará para todos ellos

Esto se ve por todo el mundo como un error para mí.Estoy totalmente de que no puede entender por qué el ModelBinder necesita comprobar mis propiedades de solo lectura (puede haber algunos tecnicismos, pero definitivamente yo no entiendo, y no estoy dispuesto a pasar el tiempo tratando).

He añadido el siguiente Modelo de Datos de Metadatos del Proveedor en para mi solución para eludir 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;
}

Usted también tendrá que agregar el siguiente Mundial.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 a GetCityStateZip() pero, a continuación, de los que no puedo enlazar en algo como silverlight fácilmente.Esto podría funcionar para una solución temporal para alguien más tiene este problema.

TENGO EL MISMO PROBLEMA!!

Para obtener más información acerca de mi problema, usted puede visitar ASP.NET MVC 2.0 sin usar el Modelo de Propiedad que se llama cuando la publicación de un producto para el servidor?

¿significa esto que necesitamos para programar nuestras propiedades con la suposición de que va a ser llamado inesperadamente (antes de propiedades que depende de configurar/inicializa etc)...si es así, esto representa un cambio en nuestras prácticas de programación y me gustaría saber cómo proceder.

mientras tanto, acabo de tener un simple 'si' comprobar que elimine el problema.

Yo estaba teniendo un problema similar, un campo que no me esperaba para ser validado estaba recibiendo un error cuando el formulario publicado hacia el controlador.Después de buscar un poco en google, me encontré con http://codeblog.shawson.co.uk/mvc-strongly-typed-view-returns-a-null-model-on-post-back/ donde se señaló que el nombre de los conflictos que podrían causar problemas.

Aunque yo no creo que mi posterior a la variable de clase en conflicto de la propiedad de los nombres, cambiar el nombre de la propiedad, recibo el error solucionado mi problema.

El mismo problema existe todavía en MVC 5.2.3, y ni siquiera es el código de validación causando el problema.El DefaultModelBinder las llamadas de los captadores fuera de su código de validación incluso si son propiedades de sólo lectura, e incluso si no hay datos de la solicitud se pasa al controlador de la coincidencia de esas propiedades.

Ver una explicación más detallada y mi solución completa aquí: https://stackoverflow.com/a/54431404/10987278.

No estoy seguro de si esa solución puede ser refactorizado para trabajar con MVC 3, pero espero que pueda ayudar a otras personas aún sufren el mismo problema en la versión posterior de MVC que tropecé con esta pregunta, como yo hice.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top