Question

I have this issue since yesterday. In my User model I have a [NotMapped] called "ConfirmPassword". I don´t save it on the database but I use it on my Create form as a always to validate the data input for new users.

Since than, it´s ok. The problem is on my [HttpPost] Edit action. I should be able to edit some user's data without type and confirm the password. I use both Password and ConfirmPassword as a way to confirm the old password and informe the new one, if I wanna change the password. But, if I don´t, I leave them blank.

I have used already the code below to be able to pass the ModelState.IsValid() condition and it worked:

ModelState["Password"].Errors.Clear();
ModelState["ConfirmPassword"].Errors.Clear();

But, just before the db.SaveChanges(), as User user view model is considered, it has both properties empty and I got:

Property: ConfirmPassword Error: The field ConfirmPassword is invalid.

The question is: How could I skip de Required model validation when I want to update an object?

I read already about custom ModelValidations with classes extending ValidationAttribute and DataAnnotationsModelValidator but I am not doing it right.

Any idea? How could I create a custom model validation that checks if the UserId property is null or not. It´s a nice way to check if I'm in Create or Edit action.

Thanks, Paulo

Was it helpful?

Solution

Using the domain objects as your ViewModel will leads you to a condition of less scalability. I would opt for seperate ViewModels specific for the Views. When i have to save the data i map the ViewModel to the Domain model and save that. In your speciific case, i would create 2 ViewModels

public class CustomerViewModel
{
  public string FirstName { set;get;}
  public string LastName { set;get;}
}

And i will Have another ViewModel which inherits from the above class, for the Create View

public class CustomerCreateViewModel :CustomerViewModel
{
   [Required]
   public string Password { set;get;}

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

Now in my Get actions, i use this ViewModel

public ActionResult Create()
{
  var vm=new CustomerCreateViewModel();
  return View(vm);
}

and of course my View(create.cshtml) is now binded to this ViewModel

@model CustomerCreateViewModel
<h2>Create Csustomer</h2/>
//Other form stuff

Similarly for My Edit Action,

public ActionResult Edit(int id)
{
  var vm=new CustomerViewModel();
  var domainCustomer=repo.GetCustomerFromID(id);
  if(domainCustomer!=null)
  {
      //This manual mapping can be replaced by AutoMapper.
      vm.FirstName=domainCustomer.FirstName;
      vm.LastName=domainCustomer.LastName;
  }
  return View(vm);
}

This view is bounded to CustomerViewModel

@model CustomerViewModel
<h2>Edit Info of @Model.FirstName</h2>
//Other form stuff

In your POST Actions, Map it back to the Domain object and Save

[HttpPost]
public ActionResult Create(CustomerCreateViewModel model)
{
  if(ModelState.IsValid)
  {
      var domainCust=new Customer();
      domainCust.FirstName=model.FirstName;
      repo.InsertCustomer(domainCust);
      //Redirect if success (to follow PRG pattern)
  }
  return View(model);
} 

Instead of writing the Mapping yourself, you may consider using AutoMapper library to do it for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top