我有用户创建的页面,显然我不希望我的用户拥有相同的用户名,所以我创建了我的验证,但是我现在有问题编辑用户。当我尝试编辑用户时,它不允许我这样做,因为它表示已经使用了用户名。但我甚至不想编辑用户名,只是密码或其他东西。
编辑:我通过调用ValidateModel()
确实犯了错误,现在我修复了这个问题,但仍然遇到了问题。
验证
public class UniqueUsername : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value == null) return true; // In Edit view you can't edit username so it's null
FinanceDataContext _db = new FinanceDataContext();
var user = _db.Users.ToList().Where(x => x.Username.ToLower() == value.ToString().ToLower()).SingleOrDefault();
if (user == null) return true;
return false;
}
}
模型
public class User
{
public int ID { get; set; }
// When I remove UniqueUsername and Remote validators everything works just fine
[Required]
[UniqueUsername(ErrorMessage = "Username is already taken")]
[Remote("CheckUsername", "User", null, ErrorMessage = "Username is allready taken", HttpMethod = "POST")]
public string Username { get; set; }
[Required]
public string Password { get; set;}
}
动作
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(User u)
{
// Get user we want to edit
var user = _db.Users.Where(x => x.ID == u.ID).SingleOrDefault();
if (user == null) return HttpNotFound();
// Set new fields manually
if (!string.IsNullOrEmpty(u.Password)) user.Password = Infrastructure.Encryption.SHA256(u.Password);
ModelState.Remove("Username"); // this doesen't seem to do much...
_db.SaveChanges(); // validation error here
return Content(Infrastructure.Helper.SerializeObject(u));
}
错误
一个或多个实体的验证失败。看到 'EntityValidationErrors'属性以获取更多详细信息。
我知道为什么它会让我失误。因为他检查用户名是否已被占用,当然已经采取了,但我想验证用户名是否仅在CREATE上获取,而不是在EDIT上(因为您无法更改用户名)
答案 0 :(得分:3)
您的编辑方法会加载具有用户名的User
实体。之后你调用ValidateModel
来检查数据库中是否有User
用户名,如果是,则返回false(无效)。嗯,当然有一个,因为你刚加载它!该错误表明您的IsValid方法返回false。
您的问题的解决方案是检查用户名是否已存在但ID是否不同。将验证更改为此代码:
public class UniqueUsername : ValidationAttribute
{
public override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null) return ValidationResult.Success; // In Edit view you can't edit username so it's null
var currentUser = validationContext.ObjectInstance as User;
FinanceDataContext _db = new FinanceDataContext();
var user = _db.Users.ToList().Where(x => x.Username.ToLower() == value.ToString().ToLower() && x.ID != currentUser.ID).SingleOrDefault();
if (user == null) return ValidationResult.Success;
return new ValidationResult("Username exists");
}
}
答案 1 :(得分:0)
我不确定你在这里做了什么,因为你正在验证刚从数据库中取出的模型,是否已经验证过了?
发布的用户模型(u)在发布时已经过验证,您可以通过以下方式验证其验证:
if(ModelState.IsValid)
如果这不验证,则可以使用*用户名在这种情况下删除特定的属性验证错误):
var username = ModelState["Username"];
if (username != null)
{
username.Errors.Clear();
}
除非您允许更改用户名,否则这应该没问题;我假设用户名将从经过验证的数据库版本保持不变。
答案 2 :(得分:0)
获取的异常是由于在将“ProxyCreationEnabled”属性设置为true的情况下创建的EF上下文。请尝试使用“context.ContextOptions.ProxyCreationEnabled = false;”
然而,就验证而言,我将放弃数据注释,而是使用更流畅的验证,这更容易使用和编写测试。
http://fluentvalidation.codeplex.com/wikipage?title=mvc&referringTitle=Documentation