Dmytro Tsiniavskyi Dmytro Tsiniavskyi - 4 months ago 24
C# Question

How to validate only part of the model in ASP .NET MVC?

I have a large model (large I mean model class contains a lot of fields/properties and each has at least one validation attribute (such as

Required
,
MaxLength
,
MinLength
etc)). Instead of creating one view with a lot of inputs for user to fill model with data I want to create several views where user will fill part of model fields and go to the next step (some kind of "wizard"). While redirecting between steps I store not fullfilled model object in
Session
. Something like below:

Model:

public class ModelClass
{
[MaxLength(100)] ...
public string Prop1{get;set;}
[MaxLength(100)] ...
public string Prop2{get;set;}
...
[Required][MaxLength(100)] ...
public string Prop20{get;set;}
}


Controller:

[HttpPost]
public ActionResult Step1(ModelClass postedModel)
{
// user posts only for example Prop1 and Prop2
// so while submit I have completly emty model object
// but with filled Prop1 and Prop2
// I pass those two values to Session["model"]
var originalModel = Session["model"] as ModelClass ?? new ModelClass();
originalModel.Prop1 = postedModel.Prop1;
originalModel.Prop2 = postedModel.Prop2;
Session["model"] = originalModel;

// and return next step view
return View("Step2");
}

[HttpPost]
public ActionResult Step2(ModelClass postedModel)
{
// Analogically the same
// I have posted only Prop3 and Prop4

var originalModel = Session["model"] as ModelClass;
if (originalModel!=null)
{
originalModel.Prop3 = postedModel.Prop3;
originalModel.Prop4 = postedModel.Prop4;
Session["model"] = originalModel;

// return next step view
return View("Step3");
}
return View("SomeErrorViewIfSessionBrokesSomeHow")
}


Step1
view has inputs only for
Prop1
and
Prop2
, Step2 view contains inputs for
Prop3
and
Prop4
etc.

BUT HERE IS THE THING

When user is on, for example, step 1, and fills Prop1 with value more than 100 characters length client side validation works fine. But, of course , I have to validate this value and on the server side in controller. If I had full model I'd just do the following:

if(!ModelState.IsValid) return View("the same view with the same model object");


so user has to fill the form again and correct.
BUT on step 1 user has filled only 2 properties of 20, and I need to validate them. I can't use
ModelState.IsValid
because model state will be invalid. As You can see
Prop20
is marked with
[Required]
attribute, when user submits
Prop1
and
Prop2
,
Prop20
is null and that's why
ModelState
is invalid. Of course I could allow user to go to step2, fill all of the steps and validate model state only on the last step but I don't want to allow user to go to step 2 if he filled step 1 incorrect. And I want this validation in controller. So the question is:
How can I validate only part of the model? How can I verify that only some of the model properties match their validation attributes?

Answer

One possible solution:

  1. Use ModelState.IsValidField(string key);

    if (ModelState.IsValidField("Name") && ModelState.IsValidField("Address"))
    { ... }
    

Then at the end when everything is done use:

if(ModelState.IsValid) { .. }