2010-01-11 95 views
2

我在使自定义数据注解工作时遇到问题,我试图添加验证属性来验证Customer(CustomerID)的UsergroupName是唯一的。使用数据注释进行自定义验证

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

public class UsergroupMetaData 
{ 
    [Required()] 
    public object CustomerID { get; set; } 

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

    [UniqueUsergroupName(????)] 
    // what to put here? 
} 



public class UniqueUsergroupName : ValidationAttribute 
{ 
    UsergroupRepository _rep = new UsergroupRepository(); 

    public override bool IsValid(object value, int customerID) 
    { 
     var x = _rep.GetUsergroups().ByUsergroupName(value).ByCustomerID(customerID); 

     // what to put here? 

     return false; 
    } 
} 

如果“count> 0”,IsValid应返回false。

我该如何解决这个问题,以便它能正常工作。 GetUsergroups()返回IQueryable。

编辑:

[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; 
    } 
} 

如何传递当前的客户ID作为参数?

/M

回答

2

你可以把这个方法
http://byatool.com/mvc/custom-data-annotations-with-mvc-how-to-check-multiple-properties-at-one-time/
为了在你的搜索ID属性,让你检查所有的“其他” UsergroupMetaData 具有相同UsergroupName。

如果您无法将其应用于您的场景,请检查并联系我。

编辑:更多解释

我的理解是,你需要检查是否有与同UsergroupName其他UsergroupMetaData对象。

假设我们会让你的整个班级成为验证不是财产:需要

[UniqueUsergroupName] 
public class UsergroupMetaData 

没有参数。我们来看看UniqueUsergroupName Validate()方法的外观如何:

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

我没有看到我应该如何在我的场景中应用它。因为它使用数据库和所有。特别是如果客户ID是可空的而不是必需的。 – 2010-01-11 12:22:19

+0

我添加了一些写在飞行代码来解释我的想法可能会在你的情况下使用。检查出来,告诉我,如果这对你有用。正如我在帖子中看到的那样,主要的做法是使整个类的验证属性不仅仅是一个特定的属性。告诉我它是怎么回事。 – Meligy 2010-01-12 01:09:48