0

I have a model in mvc as below

public class person
{
  [Required(ErrorMessage = "Please enter First Name.")]
  public string first_name {get;set;}
  [Required(ErrorMessage = "Please enter last Name")]
  public string last_name {get;set;}
   [Required(ErrorMessage = "Please enter |DOB")]
  public DateTime DOB {get;set;}


}

post method

[HttpPost]
public ActionResult save_person(person per)
{
if(per.first_name == null || per.first_name =="")
  per.first_name ="demo_first";
if(per.lastname == null || per.lastname =="")
  per.last_name ="demo_last";
if (ModelState.IsValid) //fails even assignment is done above
 {


  }

}

so using if condition I make sure the model elements will contain atleast some value but even after that ModelState.IsValid is failing and returning back to the view saying first_name and last_name is requried

how can we achieve this logic??

Sachu
  • 7,555
  • 7
  • 55
  • 94
  • 1
    What's the point of checking `ModelState.IsValid` if you are ensuring that it will be in the lines above? – Darin Dimitrov Apr 05 '17 at 06:06
  • Is `per` Null or Empty by the time your ActionResult is invoked? – Marco Apr 05 '17 at 06:08
  • @DarinDimitrov sorry its my mistake there are some other values in the model which is required and cannot assign default values..for those values i need to check the IsValid – Sachu Apr 05 '17 at 06:08
  • So you are not giving us the whole picture. It is very likely, that your model state is invalid because of any of those required properties. – Marco Apr 05 '17 at 06:09
  • @Marco no the model state error given is only for first_name and last_name – Sachu Apr 05 '17 at 06:13
  • are you sure that your object is being posted correctly?, maybe the problem is your object is never sended, can you put a breakpoint in the first line: if(per.first_name == null || per.first_name =="") And check if your Properties are been assigned, another thing... even if you assign in your controller values for firstname and lastname, it will never be validated unless you add the DOB property too, so...if your object is not reaching controller and fill that 2 fields, you need the third one too – Armando Ramirez Apr 05 '17 at 06:15
  • In this case why are `first_name` and `last_name` decorated with the `Required` attribute, if they clearly are not required? – Darin Dimitrov Apr 05 '17 at 06:16
  • @DarinDimitrov from another view same model need to be populated that time as per requirement i cannot assign default value – Sachu Apr 05 '17 at 06:17
  • @DarinDimitrov thanks for the help found the way `ModelState.Remove("first_name")` will do the needful – Sachu Apr 05 '17 at 06:18

2 Answers2

3

It is quite unclear why are the first_name and last_name properties on your model decorated with the Required attribute if they clearly are not required.

This being said, if you want to update the value of some model property in your controller you might need to ensure that you also update it in the ModelState:

if (per.first_name == null || per.first_name == "")
{
    per.first_name ="demo_first";
    ModelState.Remove("first_name");
    ModelState.SetModelValue("first_name", new ValueProviderResult(per.first_name, per.first_name, CultureInfo.InvariantCulture));
}

if (per.last_name == null || per.lastname == "")
{
    per.last_name ="demo_last";
    ModelState.Remove("last_name");
    ModelState.SetModelValue("last_name", new ValueProviderResult(per.last_name, per.last_name, CultureInfo.InvariantCulture));
}

if (ModelState.IsValid)
{
    ...
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
0

I just want to add some reference to the actual documentation to clear things up for the OP on why changing properties in the method does not solve his problem.

From the docs:

Handling Model State Errors

Model validation occurs prior to each controller action being invoked, and it is the action method’s responsibility to inspect ModelState.IsValid and react appropriately. In many cases, the appropriate reaction is to return some kind of error response, ideally detailing the reason why model validation failed.

That means, that validation has already happened when your ActionResult is invoked and the .IsValid property is set.

As per your comment: If the same model needs to be used in a different view, but with different validation requirements, it would be a good idea to create a new ViewModel with appropriate annotations:

public class AnotherPersonViewModel {
    //no required attribute
    public string last_name {get; set;}
    //no required attribute
    public string first_name {get; set;}
    //... rest of attributes
}

After this you could always map your view model to your entity model or whatever you are currently doing. But you avoid cluttering your controller with unnecessary code to remedy mistakes in your architecture.

Marco
  • 22,856
  • 9
  • 75
  • 124