Compare attribute in nested class

2019-08-14 07:32发布

问题:

I want to reuse my User class in my UserViewModel because it is too big, with too many properties.

public class User
{
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    [DataType(DataType.Password)]
    public string Password { get; set; }

    /* ... many other properties */
}

My UserViewModel have the property User and the ConfirmEmail and ConfirmPassword properties.

public class UserViewModel 
{
    public User User;

    [DataType(DataType.EmailAddress)]
    [Compare("User.Email")]
    public string ConfirmEmail { get; set; }

    [DataType(DataType.Password)]
    [Compare("User.Password")]
    public string ConfirmPassword { get; set; }
}

When I tryed [Compare("Password")] the error is:

The property UserViewModel.Password could not be found.

And with [Compare("User.Password")] the error is:

The property UserViewModel.User.Password could not be found.

There is no way to do that?

EDIT: THE SOLUTION:

I tryed againd the thepirat000 answer, but with some changes:

UserViewModel.cs

public class UserViewModel 
{
    public User User;

    public string UserEmail 
    { 
        get { return User.Email; } 
        set { User.Email = value; } 
    }

    [DataType(DataType.EmailAddress)]
    [Compare("UserEmail")]
    public string ConfirmEmail { get; set; }
}

User/Create.cshtml

On my view instead of:

<div class="form-group">
    @Html.LabelFor(model => model.User.Email)
    @Html.EditorFor(model => model.User.Email)
</div>
<div class="form-group">
    @Html.ValidationMessageFor(model => model.User.Email)
</div>

<div class="form-group pad-top">
    @Html.LabelFor(model => model.ConfirmEmail)
    @Html.EditorFor(model => model.ConfirmEmail)
    @Html.ValidationMessageFor(model => model.ConfirmEmail)
</div>

I changed model => model.User.Email to model => model.UserEmail:

<div class="form-group">
    @Html.LabelFor(model => model.UserEmail)
    @Html.EditorFor(model => model.UserEmail)
</div>
<div class="form-group">
    @Html.ValidationMessageFor(model => model.UserEmail)
</div>

<div class="form-group pad-top">
    @Html.LabelFor(model => model.ConfirmEmail)
    @Html.EditorFor(model => model.ConfirmEmail)
    @Html.ValidationMessageFor(model => model.ConfirmEmail)
</div>

Now the both client side and server side are validated.

回答1:

Maybe a duplicate: MVC3 Compare attribute and nested object properties

A workaround could be to flat the properties into your view model, like:

public class UserViewModel 
{
    public User User;
    public string UserEmail { get { return User.Email; } }

    [DataType(DataType.EmailAddress)]
    [Compare("UserEmail")]
    public string ConfirmEmail { get; set; }
}