使用两个属性的MVC3自定义验证属性

时间:2012-02-20 16:58:39

标签: asp.net-mvc-3 data-annotations customvalidator

我正在尝试编写一个自定义验证类,用于验证电子邮件尚未使用。为此,我有一个方法可以计算具有相关电子邮件地址的用户配置文件。很简单,但如果用户正在更新他们的个人资料,我需要从我提到的计数中排除他们的个人资料。所以要做到这一点,我写了以下方法:

public static bool IsEmailUnique(string email, int userprofileId)
{
    int count = -1;

    using (var db = new TRDataContext())
    {
        count = (from u in db.Userprofiles
                 where u.email == email &&
                       (userprofileId == 0 || u.userprofile_id != userprofileId)
                 select u).Count();
    }

    return count == 0;
}

这适用于新用户的自定义验证器类,因为我需要做的就是为userprofile_id传递0。

public class EmailValidatorAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        if (value == null)
            return false;

        return Userprofile.IsEmailUnique(value.ToString(), 0);
    }
}

并像这样实施

[DisplayName("Email Address")]
[Required(ErrorMessage = "Required")]
[RegularExpression(EmailRegex, ErrorMessage = "Invalid email address")]
[EmailValidator(ErrorMessage = "Already in use")]
public string email { get; set; }

但是,我现在需要将当前用户的userprofile_id传递给EmailValidator。我很难搞清楚这一点。

非常感谢任何帮助。

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以从HttpContext

中获取此内容
string currentUsername = HttpContext.Current.User.Identity.Name;

在我因提议在方法中使用HttpContext.Current而被判刑之前,你可以使用提供者:

public class EmailValidatorAttribute : ValidationAttribute
{
    public Func<HttpContextBase> ContextProvider = () => new HttpContextWrapper(HttpContext.Current);

    public override bool IsValid(object value)
    {
        if (value == null)
            return false;

        string currentUsername = ContextProvider().User.Identity.Name;

        ...
    }
}

现在可以在单元测试中轻易嘲笑。

答案 1 :(得分:2)

我遇到过类似的问题。首先,我在我的用户存储库中实现了一个'CurrentUser'方法,看起来像这样:

        //Gets the current user
        public U_USER CurrentUser()
        {
            return GetUser(HttpContext.Current.User.Identity.Name);
        }

        public U_USER GetUser(string u)
        {
            return (from us in db.U_USER
                    where us.UserName == u
                    select us).FirstOrDefault();
        }

然后,您可以使用此方法以类似于下面的方式从验证属性中获取ID:

public class EmailValidatorAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        using(UserRepository ur = new UserRepository())
        {
           if (value == null)
               return false;

           var user = ur.CurrentUser();
           return Userprofile.IsEmailUnique(value.ToString(), user.userprofile_id);
        }
    }
}