使用数据注释进行自定义验证

时间:2010-01-11 10:55:07

标签: asp.net-mvc entity-framework data-annotations

我在使自定义数据注释工作时遇到问题,我正在尝试添加验证属性,该属性验证客户的UsergroupName(CustomerID)是唯一的。

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

如何将当前的CustomerID作为参数传递?

/ M

1 个答案:

答案 0 :(得分: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;
}