嵌套对象的远程 ViewModel 验证不起作用

发布于 2024-10-18 04:16:11 字数 2050 浏览 6 评论 0原文

我有一个类 user,如下所示:

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,其中包含一个 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; }
}

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

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

编辑:

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

编辑2:

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

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

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

谢谢。

I have a class user which looks like this:

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

For the Register functionality I have created a ViewModel that holds a User object and a string for the password confirmation:

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

The first problem I run into is that I can't seem to get the validation for Compare("User.Password") to work as it does not seem to find the property on the user. Is there any way to validate the PasswordConfirmation property against the User.Password property?

The second problem is the Remote validation of the Username field. I followed David Hayden's tutorial at http://davidhayden.com/blog/dave/archive/2011/01/04/ASPNETMVC3RemoteValidationTutorial.aspx but the parameter username in the UsernameExists method is always null. Am I missing something here?

Edit:

I'm sorry but I was actually not clear enough on the error I receive for the password comparison. It works fine when filling in the fields, if the passwords do not match I will receive an error. However, when submitting the form I get the following error in the validation summary: Could not find a property named UserToRegister.Password.

Edit 2:

I have figured out part of the problem thanks to Joe's post. The remote validator posts back URL/?UserToRegister.Username=temp which obviously does not match the username parameter of my controller action. In order to map my action parameter to UserToRegister.Username the following is required:

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

This now correctly passes the parameter to the method. However I still get the error when using the Compare attribute on the password field.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

顾挽 2024-10-25 04:16:11

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

The issue with the validation of the PasswordConfigurmation property against the User.Password property is caused by a bug in in the 'jquery.validate.unobtrusive.js' file.

Originally, the jquery 'equalTo' function is:

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

You just need to modify this line:

element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];

to:

element = $(options.form).find(":input[name='" + fullOtherName + "']")[0];

Note the addition on the single quotes around the 'fullOtherName' selector. Once you've made this change, the client side validation works as expected.

执手闯天涯 2024-10-25 04:16:11

对于远程验证部分,我没有什么特别的感觉。打开 firebug 并查看正在触发的请求是什么样子可能会有所帮助。如果一切都正确连接,您应该看到大致类似这样的内容...

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

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

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

For the remote validation part nothing jumps out at me. It might be helpful to open up firebug and see what the request that is being fired looks like. You should see something roughly like this if everything is properly wired up...

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

From the request you provided, you can either use a prefix like you ended up doing or you can make your action take a user named UserToRegister and then within the action access the UserName property. This is the recommended way of dealing with remote validation of objects and might be a little easier to think about than using a Bind attribute.

For the compare validation, it appears that on the client side validation is succeeding but on the server side validation fails because the validation context does not contain a property named User.Password, only a property named User.

涙—继续流 2024-10-25 04:16:11

在这种情况下,继承似乎是添加功能的标准方法。让您的 RegistrationViewModelUserViewModel 派生怎么样:

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)
{
   ...
}

Inheritance seems like a standard way of adding functionality in this case. How about having your RegistrationViewModel derive from the UserViewModel:

public class RegistrationViewModel : UserViewModel
{
    [DisplayName("Password confirmation")]
    [Required]
    [Compare("Password", ErrorMessage = "The password do not match")]
    public string PasswordConfirmation { get; set; }
}

and:

public ActionResult UsernameExists(string Username)
{
   ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文