2010-02-08 7 views
5

Estoy intentando utilizar DataAnnotations añadir la validación de mis modelos en asp.NET MVC 2 RC2, utilizando TryUpdateModelasp.NET MVC 2 DataAnnotations UpdateModel <T> validación

 var user = UserManager.Find(id); 

     this.TryUpdateModel<IProvisioningObject>(user, form.ToValueProvider()); 

Esto actualiza el modelo, pero la validación nunca es llamado. Intenté también usar TryUpdateModel (que es el tipo de usuario directo), sin usar el proveedor de valor de formulario, utilizando ProvisioningObject directamente (que tiene los metadatos de validación), sin éxito.

Google para ejemplos sólo me da maneras de utilizar DataAnnotations mediante la unión a través de un parámetro

public ActionResult Update(User user) 

¿Qué me gusta de escenarios de actualización.

¿Algún consejo o solución?

EDIT Mis objetos son objetos autogenerados de un servicio WCF.

Hice parciales para poder agregar DataAnnotations. Llamo a TryUpdateModel tres veces porque aparentemente no admite herencia, que también creo que es mi problema con DataAnnotations. Especifico los atributos de validación para ProvisioningObject, y el enlace no busca elementos heredados como ese.

[MetadataType(typeof(ProvisioningObjectMetadata))] 
public partial class ProvisioningObject : IProvisioningObject 
{ 
    public string DisplayNameInvariant { get { return string.IsNullOrEmpty(this.DisplayName) ? this.Name : this.DisplayName; } } 
} 


[MetadataType(typeof(UserMetadata))] 
public partial class User : IUser 
{ 
} 


public class ProvisioningObjectMetadata 
{ 
    [DisplayName("Country")] 
    public string CountryIsoCode { get; set; } 

    [Required(ErrorMessageResourceType = typeof(Properties.Validation), ErrorMessageResourceName = "DisplayNameIsRequired")] 
    [TempValidator] 
    public string DisplayName { get; set; } 
} 


public class UserMetadata 
{ 
    [DisplayName("Username")] 
    public string Name { get; set; } 
} 


// Controller action 
    public ActionResult Update(string id, FormCollection form) 
    { 
     var user = UserManager.Find(id); 

     this.TryUpdateModel<IUser>(user.User, form.ToValueProvider()); 
     this.TryUpdateModel<IPerson>(user.User, form.ToValueProvider()); 
     this.TryUpdateModel<IProvisioningObject>(user.User, form.ToValueProvider()); 

     if (ModelState.IsValid) // always true 
     { 
      return Redirect; 
     } 
     else 
     { 
      return View(); 
     } 
    } 

Si añado los metadatos para DisplayName en UserMetadata, funciona como se esperaba, pero que parece muy redundante para nada. Y significaría que también tendría que copiar/pegar todas mis interfaces heredadas para que TryUpdateModel se comporte adecuadamente.

Supongo que estoy buscando un modo que no requiera que copie y pegue mis atributos de validación a las clases heredadas.

Respuesta

1

Nueva Respuesta:

"Mis objetos son objetos generados automáticamente desde un servicio WCF."

Objetos autogenerados no tendrán ningún atributo en ellos. ¿Estás definiendo tus objetos y sus atributos del lado del servidor o del lado del cliente?

Respuesta anterior: Si sus metadatos no están en IProvisioningObject, no se realizará ninguna validación. El encuadernador de modelo predeterminado de MVC2 solo sabe cómo encontrar información de validación [extra de MetadataType (buddyClass)] "extra".

Para escenarios de actualización se unen contra DTO y luego asignan los DTO, si IsValid() a sus clases de modelo principal.

+0

simplemente he tratado de hacer UpdateModel (ya que no puedo poner en una interfaz MetadataType) y no cambia nada. Creé un validador temporal y parece que nunca llega al método IsValid. Para el escenario de actualización, no estoy seguro de seguirte. Si tiene buenos enlaces a blogs o ejemplos, eso sería suficiente para comenzar. Gracias por su entrada! –

+0

¿Puedes publicar más código por favor? No tengo claro a qué intentas más. – jfar

+0

Comentario de nueva respuesta: los atributos son del lado del cliente. Utilizo clases parciales para agregar los atributos adecuados a los objetos generados automáticamente. –

0

¿Cómo sabes que no se está llamando a la validación? ¿Estás verificando ModelState.IsValid en tu controlador de actualización y descubriendo que está volviendo erróneamente cierto?

Un patrón actualización típica es:

UpdateModel(model); 
if(!ModelState.IsValid) return View(model); 
return RedirectToAction("Index"); 

Si usted está esperando un poco de "IsValid" en su modelo a ser llamado de forma automática, eso no sucederá. Las anotaciones de datos funcionan entre bastidores con el diccionario ModelState en la clase base del Controlador.

+0

ModelState.IsValid es siempre verdadero, incluso si pongo un atributo de validación personalizado que siempre devuelve falso. Un punto de corte en ese atributo de validación nunca se golpea tampoco. Funciona si pongo la validación en el tipo y no en la interfaz. Voy a pegar más código en un segundo. –

+0

¿Ha intentado colocar su atributo de tipo de metadata en su declaración de clase? Ejemplo: interfaz IDataObject {...} contiene DataAnnotations ... [MetadataType (typeof (IDataObject))] clase DataObject {....} – kmehta

+0

Mehta mismo problema. Funciona si pongo DataAnnotations en la interfaz, pero no quiero duplicar la validación de la clase/interfaz principal. –

Cuestiones relacionadas