0

I have a "New user" form both for admins and for regular users. Both form use the RegisterModel

public class RegisterModel
{
    [Required]
    public string Name { get; set; }

    public string Email { get; set; }

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

The difference is that on my front end "New user" page I want users to provide their own password. But in back end, I want the system to generate the password.

Since I use the same RegisterModel for both forms, I get a validateion error in the back end saying Password is required..

I thought, I could solve this by adding this to my controller:

    [HttpPost]
    public ActionResult New(RegisterModel model)
    {
        model.Password = Membership.GeneratePassword(6, 1);

        if (TryValidateModel(model))
        {
            // Do stuff
        }

        return View(model);
    }

But I still get the error message Password is required.. Why is this the issue when I do call TryValidate in my controller?

What would be best practice for this issue, create a separate RegisterModelBackEnd or are there any other solutions to this?

Martin at Mennt
  • 5,677
  • 13
  • 61
  • 89

1 Answers1

1

When updating model manually, you do not need to use it as parameter in Action. Also, use this overload that lets you specify only the properties on which binding will occur.

protected internal bool TryUpdateModel<TModel>(
    TModel model,
    string[] includeProperties
)
where TModel : class

So, the working code will be

[HttpPost]
public ActionResult New()
{
    RegisterModel model = new RegisterModel();
    model.Password = Membership.GeneratePassword(6, 1);

    if (TryValidateModel(model, new string[] {"Name", "Email"}))
    {
        // Do stuff
    }

    return View(model);
}

You can make this even simpler, using BindAttribute

[HttpPost]
public ActionResult New([Bind(Exlude="Password")]RegisterModel model)
{
    if(ModelState.IsValid)
    {
       model.Password = Membership.GeneratePassword(6, 1);
       // Do Stuff
    }

    return View(model);
}

And finally simplest and the best way

Define separate view models

archil
  • 39,013
  • 7
  • 65
  • 82
  • Thank you for your comments, I tried the `[Bind(Exclude="Password")]` which looked promising, but I still got the error. I guess I have to add a hidden field in the view for the password for it to work. I will go for `Defining separate view models` I was hoping this was the best way, but did not know if it was best practice or not. – Martin at Mennt Oct 04 '11 at 10:47
  • Yes, that is best way and practice. View models should be defined for all the concrete cases separately. There's no point in using same models plus "hacking" approach for different scenarios. – archil Oct 04 '11 at 10:55