1

我为唯一用户名创建了验证,现在我无法编辑我的用户。这是说用户名已经被使用,这是有道理的,因为它是由我试图编辑的用户使用的。我什至不想编辑用户名,但由于这个错误,我也无法编辑任何其他字段。

如何为我的 EDIT 操作禁用唯一用户名验证?

验证器

public override bool IsValid(object value)
{
    if (value == null) return false;
    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;
}

行动

[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 values and save changes
    user.Address = u.Address;
    if (!string.IsNullOrEmpty(u.Password)) user.Password = Infrastructure.Encryption.SHA256(u.Password);
    _db.SaveChanges(); // validation error

    return null;
}

模型

public class User
{
    public int ID { get; set; }

    [Required]
    [UniqueUsername(ErrorMessage = "Username is already taken")]
    public string Username { get; set; }

    [Required]
    public string Password { get; set; }

    public string Address { get; set; }
}

错误

一个或多个实体的验证失败。有关更多详细信息,请参阅“EntityValidationErrors”属性。

4

4 回答 4

2

在 UniqueUsername 属性的“AdditionalFields”参数中传递“ID”属性,所以我猜你的代码应该是这样的

类属性:

[Required]
[UniqueUsername(ErrorMessage = "Username is already taken", AdditionalFields = "ID")]
public string Username { get; set; }

验证动作:

public ActionResult UniqueUsername(string userName, int id)
{
    FinanceDataContext _db = new FinanceDataContext();
    var user = _db.Users.ToList().SingleOrDefault(x => x.Username.ToLower() == value.ToString().ToLower() && x.ID != id);
    return Json(user == null, JsonRequestBehavior.AllowGet);
}

希望这会有所帮助!

于 2012-11-01T17:44:05.883 回答
1

您能否将用户 ID 传递给 IsValid 方法并确保返回的用户没有相同的用户 ID?

于 2012-11-01T17:35:49.413 回答
1

我想贡献一件事。

这段代码:

var user = _db.Users.ToList().Where(x => x.Username.ToLower() == value.ToString().ToLower()).SingleOrDefault();

不是执行的,因为当您执行 a 时,您会ToList()执行整个查询。在这种情况下,您正在做的是从数据库中检索所有用户,然后他们在内存中进行过滤。

我建议你这样做:

_db.Users.Where(x => x.Username.ToLower() == value.ToString().ToLower()).SingleOrDefault();

由于您只想检索一条记录,因此无需调用该ToList()方法。到最后就够SingleOrDefault()了。

于 2012-11-01T17:55:12.320 回答
0

通过将整个对象传递给我的验证器然后检查 id 和用户名来修复它。

public override bool IsValid(object value)
{
    var user = (User)value;
    if (user == null) return true;

    FinanceDataContext _db = new FinanceDataContext();
    var u = _db.Users.Where(x => x.Username.ToLower() == user.Username.ToLower() && x.ID != user.ID).SingleOrDefault();
    if (u == null) return true;
    return false;
}
于 2012-11-01T18:09:13.223 回答