问题
我知道在 MVC 中有很多方法可以进行模型验证,并且有很多关于这个主题的文档。但是,我不太确定验证模型属性的最佳方法是相同类型的“子模型”。
请记住以下几点
- 我仍然想从
TryUpdateModel/TryValidateModel
方法中获利 - 这些“子模型”中的每一个都有强类型视图
- 有一个用于
MainModel
呈现整体显示视图的类的强类型视图
这可能听起来有点混乱,但我会抛出一些代码来澄清。以以下类为例:
主要型号:
class MainModel{
public SomeSubModel Prop1 { get; set; }
public SomeSubModel Prop2 { get; set; }
}
一些子模型:
class SomeSubModel{
public string Name { get; set; }
public string Foo { get; set; }
public int Number { get; set; }
}
主模型控制器:
class MainModelController{
public ActionResult MainDisplay(){
var main = db.retrieveMainModel();
return View(main);
}
[HttpGet]
public ActionResult EditProp1(){
//hypothetical retrieve method to get MainModel from somewhere
var main = db.retrieveMainModel();
//return "submodel" to the strictly typed edit view for Prop1
return View(main.Prop1);
}
[HttpPost]
public ActionResult EditProp1(SomeSubModel model){
if(TryValidateModel(model)){
//hypothetical retrieve method to get MainModel from somewhere
var main = db.retrieveMainModel();
main.Prop1 = model;
db.Save();
//when succesfully saved return to main display page
return RedirectToAction("MainDisplay");
}
return View(main.Prop1);
}
//[...] similar thing for Prop2
//Prop1 and Prop2 could perhaps share same view as its strongly
//typed to the same class
}
我相信这段代码到目前为止都是有意义的(如果不是这样,请纠正我)因为TryValidateModel()
正在验证一个没有ValidationAttribute
.
问题出在哪里,哪里是最好的地方,或者什么是最好和最优雅的方式来对不同的验证约束,Prop1
同时Prop2
仍然利用TryValidateModel()
而不是用条件语句填充 Edit 方法和ModelState.AddModelError()
通常你可以在SomeSubModel
类中有验证属性,但在这种情况下它不起作用,因为每个属性都有不同的约束。
其他选项是MainModel
类中可能有自定义验证属性,但在这种情况下它也不起作用,因为SomeSubModel
对象直接传递给视图并且在验证时没有对其MainModel
对象的引用。
我能想到的唯一剩下的选择是每个属性的 ValidationModel,但我并不是最好的方法。
解决方案
这是我根据@MrMindor 的回答实施的解决方案。
基础 ValidationModel 类:
public class ValidationModel<T> where T : new()
{
protected ValidationModel() {
this.Model = new T();
}
protected ValidationModel(T obj) {
this.Model = obj;
}
public T Model { get; set; }
}
Prop1 的验证模型
public class Prop1ValidationModel:ValidationModel<SomeSubModel>
{
[StringLength(15)]
public string Name { get{ return base.Model.Name; } set { base.Model.Name = value; } }
public Prop1ValidationModel(SomeSubModel ssm)
: base(ssm) { }
}
Prop2 的验证模型
public class Prop2ValidationModel:ValidationModel<SomeSubModel>
{
[StringLength(70)]
public string Name { get{ return base.Model.Name; } set { base.Model.Name = value; } }
public Prop2ValidationModel(SomeSubModel ssm)
: base(ssm) { }
}
行动
[HttpPost]
public ActionResult EditProp1(SomeSubModel model){
Prop1ValidationModel vModel = new Prop1ValidationModel(model);
if(TryValidateModel(vModel)){
//[...] persist data
//when succesfully saved return to main display page
return RedirectToAction("MainDisplay");
}
return View(model);
}