2010-01-11 93 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