2010-01-11 10 views
2

Je n'arrive pas à faire fonctionner mes notifications de données personnalisées. J'essaie d'ajouter un attribut de validation qui confirme que le nom de groupe d'utilisateurs d'un client (CustomerID) est unique. Le IsValid devrait renvoyer false si le "count> 0".Validation personnalisée avec des annotations de données

Comment puis-je résoudre ce problème pour que cela fonctionne. GetUsergroups() renvoie IQueryable.

EDIT:

[MetadataType(typeof(UsergroupMetaData))] 
public partial class Usergroup { } 

public class UsergroupMetaData 
{ 
    public object CustomerID { get; set; } 

    [Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "UsergroupNameRequired")] 
    [UniqueUsergroupName(ErrorMessageResourceType= typeof(Resources), ErrorMessageResourceName = "UsergroupNameExists")] 
    public object UsergroupName { get; set; } 


} 


public class UniqueUsergroupName : ValidationAttribute 
{ 

    UsergroupRepository _rep = new UsergroupRepository(); 

    public override bool IsValid(object value, int customerID) 
    { 

     int usergroups = _rep.GetUsergroups().ByCustomerID(customerID).ByUsergroupName(value.ToString()).Count(); 

     return usergroups >0; 
    } 
} 

Comment puis-je passer le courant CustomerID comme paramètre?

/M

Répondre

2

Vous pouvez appliquer cette approche
http://byatool.com/mvc/custom-data-annotations-with-mvc-how-to-check-multiple-properties-at-one-time/
Pour inclure la propriété ID dans votre recherche, de sorte que vous vérifiez pour tous les « autres » UsergroupMetaData qui ont le même UsergroupName.

Cochez-la et contactez-moi si vous avez des difficultés à l'appliquer à votre scénario.

Edit: Plus explication

Ma compréhension est que vous devez vérifier s'il y a d'autres objets UsergroupMetaData avec le même UsergroupName.

Supposons que nous allons faire le validateur devenir sur toute votre classe pas la propriété:

[UniqueUsergroupName] 
public class UsergroupMetaData 

Aucun paramètre sont nécessaires. Voyons comment la méthode UniqueUsergroupName Validate() ressemblera:

public override Boolean IsValid(Object value) 
{ 
    var usergroupName = value != null ? value.ToString() : null; 
    //We don't validate empty fields, the Required validator does that 
    if(string.IsNullOrEmpty(usergroupName)) return true; 

    Type objectType = value.GetType(); 
    //Get the property info for the object passed in. This is the class the attribute is 
    // attached to 
    //I would suggest caching this part... at least the PropertyInfo[] 
    PropertyInfo[] neededProperties = 
    objectType.GetProperties(); 

    var customerIdProperty = neededProperties 
    .Where(propertyInfo => propertyInfo.Name == "CustomerID") 
    .First(); 
    var customerId = (int?) customerIdProperty.GetValue(value, null); 

    var usergroupNameProperty = neededProperties 
    .Where(propertyInfo => propertyInfo.Name == "UsergroupName") 
    .First(); 
    var usergroupName = (string) customerIdProperty.GetValue(value, null); 

    // Now I don't userstand why the blog post author did all this reflection stuff to 
    // get the values of the properties. I don't know why he just didn't d something like: 
    // var usergroup = (Usergroup) value; 
    // var customerId = usergroup.CustomerId; 
    // var usergroupName = usergroup.UsergroupName; 
    // 
    //I think reflection was not needed here. Try both ways anyway. 
    // The next lines should not be different regardless of whether you used reflection. 
    // 

    //We don't validate empty fields, the Required validator does that 
    if(string.IsNullOrEmpty(usergroupName)) return true; 

    //Now you have the customerId and usergroupName. Use them to validate. 
    //If I'm using LINQ (for explanation only) it'd be something like: 
    // Assuming _rep.GetUsergroups() returns IQueryable (only for explanation): 
    int numberOfOtherUsergroupsWithSameName = 
     _rep.GetUsergroups() 
       .Where(g => g.UsergroupName == usergroupName && g.CustomerId != customerId) 
       .Count(); 
    return numberOfOtherUsergroupsWithSameName == 0; 
} 
+0

Je ne vois pas comment je devrais l'appliquer dans mon scénario. Comme il utilise la base de données et tout. Surtout si CustomerID serait nullable et non requis. –

+0

J'ai ajouté un code écrit à la volée pour expliquer comment je pense que l'idée pourrait être utilisée dans votre situation. Vérifiez-le et dites-moi si cela fonctionne pour vous. La capture principale que je vois dans la publication est de faire en sorte que l'attribut de validation fonctionne pour toute la classe et pas seulement pour une certaine propriété. Dites-moi comment ça se passe. – Meligy

Questions connexes