Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore Required attribute when saving on edit page

I have a model class that has a couple of required fields:

public class UserMetadata
{
   [Required(ErrorMessage = "Please enter a name.")]
   public string Name { get; set; }

   [Required(ErrorMessage = "Please enter a password.")]
   public string Password { get; set; }
}

On the create view, if I don't give a name and/or password, then the validation summary errors appears. All nice and good. For the edit view, I'm only displaying the 'Name' field - I don't to show the 'Password' field.

When I save my changes on the edit page, the validation summary error appears saying that I must enter a password.

How can I control the validation of the password field, so that for the edit view, it should not bother with it? Or, am I approaching this the wrong way? I still want the 'Name' field validation to work on the edit view.

EDIT:

For my MVC project, I'm using Entity Framework. Thus, I have a 'UserMetadata' class defined so that I can attached things like '[Required]' onto certain fields on the 'User' class (which is in the EDMX file).

I should also explain that I'm using a view model eg 'UserEditViewModel' which has a property 'User' attached to it. So on my post:

[HttpPost]
public ActionResult Edit(UserEditViewModel inputViewModel)
{

    if(ModelState.IsValid) { inputViewModel.User blah.... }

}

Think I rushed a bit when typing this question. Any other missing information you think is important, then please give me a shout.

Cheers. Jas.

like image 233
Jason Evans Avatar asked May 05 '11 15:05

Jason Evans


3 Answers

I ended up doing this in my action method:

ModelState.Remove("User.Password");

Now my code runs fine, only raising validation errors on the "Name" field, which is what I wanted..

like image 114
Jason Evans Avatar answered Sep 21 '22 11:09

Jason Evans


ModelState.Remove("User.Password") did not work for me in MVC 3.

However, the following worked.

Option 1:

ModelState.Remove("Password")

Option 2:

ModelState.Where(m => m.Key == "Password").FirstOrDefault().Value.Errors.Clear()
like image 38
ykay Avatar answered Sep 22 '22 11:09

ykay


Assuming you're using your UserMetadata class as a view model, you should be using a different view model per page (view).

e.g.

public class UserMetaDataCreate
{
    [Required(ErrorMessage = "Please enter a name.")]
    public string Name { get; set; }

    [Required(ErrorMessage = "Please enter a password.")]
    public string Password { get; set; }
}

and UserMetaDataEdit

public class UserMetaDataEdit
{
    [Required(ErrorMessage = "Please enter a name.")]
    public string Name { get; set; }
}

Basically, if the edit view doesn't need password, it shouldn't be in the model anyway.

In your controller,

public ActionResult Create()
{
    return View(new UserMetaDataCreate());
}
// and subsequent post actions
[HttpPost]
public ActionResult Edit(UserMetaDataEdit vm)
{
    if(ModelState.IsValid)
    {
        // do something
    }
    else
        return View(vm);
}

Of course, you could go about some inheritance as your models become more complex e.g.

public class UserMetaData
{
    [Required(ErrorMessage = "Please enter a name.")]
    public string Name { get; set; }
}

And subclass your view models

public class UserMetaDataEdit
{
    [Required(ErrorMessage = "Please enter a password.")]
    public string Password { get; set; }
}

public class UserMetaDataCreate
{

}

But, I'm not sure that makes sense contextually since UserMetaData does semantically include a password.

like image 23
David Fox Avatar answered Sep 24 '22 11:09

David Fox