我正在尝试编写一个自定义验证类,用于验证电子邮件尚未使用。为此,我有一个方法可以计算具有相关电子邮件地址的用户配置文件。很简单,但如果用户正在更新他们的个人资料,我需要从我提到的计数中排除他们的个人资料。所以要做到这一点,我写了以下方法:
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。我很难搞清楚这一点。
非常感谢任何帮助。
谢谢!
答案 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);
}
}
}