2010-02-08 7 views
5

J'essaie d'utiliser DataAnnotations ajouter la validation à mes modèles dans asp.NET MVC 2 RC2, en utilisant TryUpdateModelasp.NET MVC 2 DataAnnotations UpdateModel <T> validation

 var user = UserManager.Find(id); 

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

Cela met à jour le modèle, mais la validation n'est jamais appelé. J'ai également essayé TryUpdateModel (qui est le type direct d'utilisateur), n'utilisant pas le fournisseur de valeur de formulaire, en utilisant directement ProvisioningObject (qui a les métadonnées de validation), en vain.

recherche sur Google pour des exemples me donne des moyens d'utiliser DataAnnotations en se liant par un paramètre

public ActionResult Update(User user) 

Ce que je n'aime pas pour les scénarios de mise à jour.

Des conseils et/ou des solutions?

EDIT Mes objets sont des objets générés automatiquement à partir d'un service WCF.

je fait pour être en mesure partials ajouter DataAnnotations. J'appelle TryUpdateModel trois fois car il ne prend apparemment pas en charge l'héritage, ce qui est également mon problème avec DataAnnotations. Je spécifie les attributs de validation pour ProvisioningObject, et la liaison ne cherche pas les choses héritées comme ça.

[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 j'ajoute les métadonnées DisplayName dans UserMetadata, il fonctionne comme prévu, mais cela semble très redondant pour rien. Et cela signifierait que je devrais également copier/coller toutes mes interfaces héritées afin que TryUpdateModel se comporte de manière appropriée.

Je suppose que je suis à la recherche d'une manière qui ne me demande pas de copier-coller mes attributs de validation des classes héritées.

Répondre

1

Nouvelle réponse:

"Mes objets sont des objets générés automatiquement à partir d'un service WCF."

Les objets générés automatiquement n'auront aucun attribut sur eux. Définissez-vous vos objets et leurs attributs côté serveur ou côté client?

Ancienne réponse: Si vos métadonnées ne sont pas sur IProvisioningObject, aucune validation ne sera effectuée. Le classeur de modèle par défaut MVC2 ne sait comment trouver des informations de validation "extra" [MetadataType (buddyClass)].

Pour les scénarios de mise à jour se lient contre DTO et les DTO map, si IsValid() à vos principales classes de modèle.

+0

Je viens d'essayer de le faire UpdateModel (puisque je ne peux pas mettre MetadataType sur une interface) et il ne change rien. J'ai créé un validateur temporaire et il ne semble jamais avoir touché la méthode IsValid. Pour le scénario Mise à jour, je ne suis pas sûr de vous suivre. Si vous avez de bons liens vers des blogs ou des exemples, ce serait suffisant pour me lancer. Merci pour votre contribution! –

+0

Pouvez-vous poster plus de code s'il vous plaît? Je ne suis pas clair sur ce que vous essayez de faire plus. – jfar

+0

New Answer comment: Les attributs sont côté client. J'utilise des classes partielles pour ajouter les attributs appropriés aux objets générés automatiquement. –

0

Comment savez-vous que la validation n'est pas appelée? Vérifiez-vous ModelState.IsValid dans votre contrôleur de mise à jour et constatez qu'il est erroné à nouveau vrai?

Un modèle de mise à jour est typique:

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

Si vous attendez un peu « IsValid » sur votre modèle pour être automatiquement appelé, cela ne se produira pas. Les annotations de données fonctionnent dans les coulisses avec le dictionnaire ModelState sur la classe de base Controller.

+0

ModelState.IsValid est toujours vrai, même si je mets un attribut de validation personnalisé qui renvoie toujours false. Un point d'arrêt dans cet attribut de validation n'est jamais touché non plus. Cela fonctionne si je mets la validation sur le type et non sur l'interface. Je vais coller plus de code dans une seconde. –

+0

Avez-vous essayé de placer votre attribut de type de métadonnées dans votre déclaration de classe? Exemple: l'interface IDataObject {...} contient DataAnnotations ... [MetadataType (typeof (IDataObject))] classe DataObject {....} – kmehta

+0

Mehta Même problème. Cela fonctionne si je mets le DataAnnotations directement sur l'interface, mais je ne veux pas dupliquer la validation de la classe/interface parente. –

1

Mettre en œuvre IDataErrorInfo interface dans votre classe partielle Vous devrez écrire une validation personnalisée pour chaque champ (où vous pouvez utiliser la classe d'annotation de données pour valider chaque propriété requise)

Si vous avez besoin exemple de code alors laissez-moi savoir. Je vais l'écrire pour vous!

source: http://www.asp.net/(S(pdfrohu0ajmwt445fanvj2r3))/learn/mvc/tutorial-37-cs.aspx

Questions connexes