我有一个类用户,如下所示:
public class User
{
public int UserId { get; set; }
[Required(ErrorMessage = "A username is required.")]
[StringLength(20, ErrorMessage = "Your username must be 4-20 characters.", MinimumLength = 4)]
[RegularExpression("^[a-zA-Z0-9]*$", ErrorMessage = "Your username can only consist of letters and numbers.")]
[Remote("UsernameExists", "RemoteValidation", ErrorMessage = "Username is already taken")]
public string Username { get; set; }
[Required(ErrorMessage = "A password is required.")]
[MinLength(4, ErrorMessage = "Your password must have at least 4 letters.")]
public string Password { get; set; }
[Required(ErrorMessage = "An email address is required.")]
public string Email { get; set; }
}
对于Register功能,我创建了一个ViewModel,它包含一个User对象和一个用于密码确认的字符串:
public class RegistrationViewModel
{
public User User { get; set; }
[DisplayName("Password confirmation")]
[Required, Compare("User.Password", ErrorMessage = "The password do not match")]
public string PasswordConfirmation { get; set; }
}
我遇到的第一个问题是我似乎无法通过比较验证(“User.Password”),因为它似乎没有找到用户的属性。有没有办法根据User.Password属性验证PasswordConfirmation属性?
第二个问题是用户名字段的远程验证。我在http://davidhayden.com/blog/dave/archive/2011/01/04/ASPNETMVC3RemoteValidationTutorial.aspx跟踪了David Hayden的教程,但UsernameExists方法中的参数username始终为null。我在这里错过了什么吗?
编辑:
我很抱歉,但实际上对于我收到的密码比较错误我并不清楚。填写字段时工作正常,如果密码不匹配,我将收到错误。但是,在提交表单时,我在验证摘要中收到以下错误:找不到名为UserToRegister.Password的属性。
编辑2:
感谢Joe的帖子,我已经找到了部分问题。远程验证器回发URL /?UserToRegister.Username = temp,这显然与我的控制器操作的用户名参数不匹配。为了将我的action参数映射到UserToRegister.Username,需要以下内容:
public ActionResult UsernameExists([Bind(Prefix = "UserToRegister.Username")]string username)
现在正确地将参数传递给方法。但是,在密码字段上使用Compare属性时仍然会出现错误。
感谢。
答案 0 :(得分:5)
针对User.Password属性验证PasswordConfigurmation属性的问题是由'jquery.validate.unobtrusive.js'文件中的错误引起的。
最初,jquery的“equalTo”函数是:
adapters.add("equalto", ["other"], function (options) {
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];
setValidationValues(options, "equalTo", element);
});
您只需修改此行:
element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];
为:
element = $(options.form).find(":input[name='" + fullOtherName + "']")[0];
请注意'fullOtherName'选择器周围的单引号添加。完成此更改后,客户端验证将按预期工作。
答案 1 :(得分:1)
对于远程验证部分,我什么都没有跳出来。打开firebug并查看正在触发的请求是什么样子可能会有所帮助。如果一切都正确连接,你应该看到类似的东西......
的http://本地主机:14547 / [控制器] / [ActionName] [PARAMNAME] = [paramValue]
根据您提供的请求,您可以使用您最终执行的前缀,也可以使您的操作采用名为UserToRegister的用户,然后在操作中访问UserName属性。这是处理对象远程验证的推荐方法,可能比使用Bind属性更容易思考。
对于比较验证,似乎在客户端验证成功,但在服务器端验证失败,因为验证上下文不包含名为User.Password的属性,只有名为User的属性。
答案 2 :(得分:0)
在这种情况下,继承似乎是添加功能的标准方法。如何让RegistrationViewModel
来自UserViewModel
:
public class RegistrationViewModel : UserViewModel
{
[DisplayName("Password confirmation")]
[Required]
[Compare("Password", ErrorMessage = "The password do not match")]
public string PasswordConfirmation { get; set; }
}
和
public ActionResult UsernameExists(string Username)
{
...
}