10

我有一个看起来像这样的类用户:

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; }
}

对于注册功能,我创建了一个 ViewModel,其中包含一个用户对象和一个用于密码确认的字符串:

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; }
}

我遇到的第一个问题是我似乎无法验证 Compare("User.Password") 的工作,因为它似乎没有找到用户的属性。有没有办法根据 User.Password 属性验证 PasswordConfirmation 属性?

第二个问题是用户名字段的远程验证。我在http://davidhayden.com/blog/dave/archive/2011/01/04/ASPNETMVC3RemoteValidationTutorial.aspx遵循了 David Hayden 的教程,但 UsernameExists 方法中的参数用户名始终为空。我在这里错过了什么吗?

编辑:

对不起,但我实际上对密码比较收到的错误还不够清楚。填写字段时效果很好,如果密码不匹配,我将收到错误消息。但是,在提交表单时,我在验证摘要中收到以下错误:找不到名为 UserToRegister.Password 的属性。

编辑2:

由于乔的帖子,我已经解决了部分问题。远程验证器发回 URL/?UserToRegister.Username=temp 这显然与我的控制器操作的用户名参数不匹配。为了将我的操作参数映射到 UserToRegister.Username,需要以下内容:

public ActionResult UsernameExists([Bind(Prefix = "UserToRegister.Username")]string username)

这现在可以正确地将参数传递给方法。但是,在密码字段上使用比较属性时,我仍然会收到错误消息。

谢谢。

4

3 回答 3

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”选择器周围的单引号中添加的内容。进行此更改后,客户端验证将按预期工作。

于 2012-03-01T20:33:22.173 回答
1

对于远程验证部分,我没有任何反应。打开 firebug 并查看正在触发的请求可能会有所帮助。如果一切都正确连接,你应该会看到大致这样的东西......

http://localhost:14547/[Controller]/[ActionName]?[ParamName]=[paramValue]

从您提供的请求中,您可以使用最终使用的前缀,也可以让您的操作采用名为 UserToRegister 的用户,然后在操作中访问 UserName 属性。这是处理对象远程验证的推荐方法,并且可能比使用 Bind 属性更容易考虑。

对于比较验证,似乎客户端验证成功但服务器端验证失败,因为验证上下文不包含名为 User.Password 的属性,仅包含名为 User 的属性。

于 2011-02-17T01:21:49.207 回答
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)
{
   ...
}
于 2011-02-17T07:11:16.050 回答