我有一个大模型(大我的意思是模型类包含很多字段/属性,每个都至少有一个验证属性(例如Required
,MaxLength
等MinLength
))。我不想创建一个包含大量输入的视图来让用户用数据填充模型,我想创建几个视图,用户将在其中填充部分模型字段并进入下一步(某种“向导”)。在步骤之间重定向时,我将未填充的模型对象存储在Session
. 如下所示:
模型:
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;}
}
控制器:
[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
视图只有Prop1
and的输入Prop2
,Step2 视图包含 and 的输入Prop3
等Prop4
。
但事情是这样的
例如,当用户打开时,步骤 1 并用长度超过 100 个字符的值填充 Prop1 客户端验证工作正常。但是,当然,我必须在控制器的服务器端验证这个值。如果我有完整的模型,我只需执行以下操作:
if(!ModelState.IsValid) return View("the same view with the same model object");
所以用户必须再次填写表格并更正。
但是在第 1 步用户只填写了 20 个属性,我需要验证它们。我不能使用ModelState.IsValid
,因为模型状态将无效。如您所见Prop20
,标记为[Required]
属性,当用户提交时Prop1
,Prop2
为Prop20
空,这ModelState
就是无效的原因。当然,我可以允许用户进入第 2 步,填写所有步骤并仅在最后一步验证模型状态,但我不想让用户进入第 2 步,如果他填写的第 1 步不正确。我希望在控制器中进行此验证。所以问题是:
我怎样才能只验证模型的一部分?如何验证只有部分模型属性与它们的验证属性匹配?