2010-12-15 69 views
4

Je veux effectuer une validation de formulaire simple dans mon contrôleur.Comment puis-je ajouter des erreurs à ModelState en utilisant la clé correcte dans ASP.NET MVC?

Voici un extrait de l'action du contrôleur:

// other code 

      if (!string.IsNullOrEmpty(editModel.NewPassword) 
       && editModel.RepeatNewPassword != editModel.NewPassword)    { 
       // problem line... How to I get the key from editModel? 
       ModelState.AddModelError("", "The new password does not match the repeated password.") 
      } 

// other code 

Il semble que doit utiliser une chaîne comme la clé de l'erreur. Est-il possible que je puisse générer la clé de corect à partir du modèle, ou devrais-je simplement vérifier quel nom d'entrée retourne Html.PasswordFor(x => x.NewPassword)?

Répondre

2

Ou dans votre ViewModel vous pouvez le faire

public class ClassName 
    { 
     public string Password { get; set; } 

     [Compare("Password" , "Password Must Match")] 
     public string ConfirmPassword { get; set; } 
    } 

c'est nouveau pour mvc3 et vous pouvez implémenter votre attribut personnalisé comme ça assez facile dans mvc3Parce que IsValid reçoit maintenant un paramètre ValidationContext qui contient des informations sur la validation en cours, comme le type du modèle et des métadonnées qui lui sont associées. Vous pouvez donc utiliser la réflexion pour obtenir d'autres propriétés et leur valeur CompareAttribute en a fait usage caractéristique

2

Pas exactement ce que vous demandez, mais résoudre votre problème:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] 
public sealed class PropertiesMustMatchAttribute : ValidationAttribute 
{ 
    #region [ Fields ] 

    /// <summary> 
    /// Defines the default error messsage 
    /// </summary> 
    private const string DefaultErrorMessage = "'{0}' and '{1}' do not match."; 

    /// <summary> 
    /// Defines a typeId 
    /// </summary> 
    private readonly object typeId = new object(); 

    #endregion 

    #region [ Constructors ] 

    /// <summary> 
    /// Initializes a new instance of the PropertiesMustMatchAttribute class. 
    /// </summary> 
    /// <param name="originalProperty">The original property name</param> 
    /// <param name="confirmProperty">The confirm (or match) property name</param> 
    public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty) 
     : base(DefaultErrorMessage) 
    { 
     this.OriginalProperty = originalProperty; 
     this.ConfirmProperty = confirmProperty; 
    } 

    #endregion 

    #region [ Properties ] 

    /// <summary> 
    /// Gets the confirm property name 
    /// </summary> 
    public string ConfirmProperty { get; private set; } 

    /// <summary> 
    /// Gets the original property name 
    /// </summary> 
    public string OriginalProperty { get; private set; } 

    /// <summary> 
    /// Gets a unique identifier for this <see cref="T:System.Attribute"/>. 
    /// </summary> 
    /// <returns>An <see cref="T:System.Object"/> that is a unique identifier for the attribute.</returns> 
    /// <filterpriority>2</filterpriority> 
    public override object TypeId 
    { 
     get 
     { 
      return this.typeId; 
     } 
    } 

    #endregion 

    #region [ Overrides ] 

    /// <summary> 
    /// Applies formatting to an error message, based on the data field where the error occurred. 
    /// </summary> 
    /// <returns>An instance of the formatted error message.</returns> 
    /// <param name="name">The name to include in the formatted message.</param> 
    public override string FormatErrorMessage(string name) 
    { 
     return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, this.OriginalProperty, this.ConfirmProperty); 
    } 

    /// <summary> 
    /// Determines whether the specified value of the object is valid. 
    /// </summary> 
    /// <returns>true if the specified value is valid; otherwise, false.</returns> 
    /// <param name="value">The value of the object to validate. </param> 
    public override bool IsValid(object value) 
    { 
     var properties  = TypeDescriptor.GetProperties(value); 
     var originalValue = properties.Find(this.OriginalProperty, true /* ignoreCase */).GetValue(value); 
     var confirmValue = properties.Find(this.ConfirmProperty, true /* ignoreCase */).GetValue(value); 
     return Equals(originalValue, confirmValue); 
    } 

    #endregion 
} 

Et puis:

[PropertiesMustMatch("NewPassword", "RepeatNewPassword ", ErrorMessage = "The new password and confirmation password do not match.")] 
public class YourModel 
{ 
    public string NewPassword {get;set;} 
    public string RepeatNewPassword {get;set;} 
} 
+0

C'est un code de service lourd. Je vais avoir besoin de temps pour le digérer. – quakkels

+0

Ce n'est pas si mal. Tout ce qu'il fait est de créer un attribut 'PropertiesMustMatch' personnalisé que vous pouvez ensuite appliquer à vos modèles de vue. Si vous créez un nouveau projet MVC2 (ou 3, je pense) par défaut dans Visual Studio, vous verrez à peu près exactement le même code et vous pourrez voir comment il est utilisé dans les modèles d'adhésion et comment il est organisé dans le projet. – TheRightChoyce

+0

Oui, un nouveau projet MVC2 est fourni avec l'attribut PropertiesMustMatch qui représente 95% de ce que j'ai posté. Je pense que tout ce que j'ai fait était d'ajouter des commentaires et des régions, ce qui explique pourquoi je viens de créer C & Ped. – ARM