复杂属性列表的MVC ModelState验证

本文关键字:ModelState 验证 MVC 属性 列表 复杂 | 更新日期: 2023-09-27 18:29:21

所以,我有一个User模型类。它有UnitViewModel的列表。

public class UserViewModel
{
    [Required(ErrorMessage="FirstName")]
    public string FirstName { get; set; }
    [Required(ErrorMessage = "LastName")]
    public string LastName { get; set; }
    public List<UnitViewModel> DesiredUnits { get; set; }
}
public class UnitViewModel
{
    public Guid? UnitID { get; set; }
    [Required(ErrorMessage = "NAMEEE")]
    public string Name { get; set; }
    public bool Selected { get; set; }
}

当我尝试创建新的User时,我会在视图中发布UserViewModel。这里我得到ModelState.IsValid false。发生这种情况的原因是Validation还检查了为null的UnitViewModel.Name属性(这是正常的,因为我创建了User,并且UnitViewModelcheckbox列表。用户从现有的UnitViewModel列表中选择UnitViewModel)。

我可以通过foreach循环以ModelState["DesiredUnits[0].UnitID"].Errors.Clear()的可怕方式修复它,但我不会。

那么,解决方案是什么呢?如何禁用模型复杂属性列表的验证?

更新
我目前正在使用的另一个解决方案是在UnitViewModel的编辑器模板中使用HiddenFor(m=>m.Name),但这种方法的缺点是,当我在编辑器模板中已经有标签时,Name是不必要的。此外,如果我有更多的必填字段,我必须为每个字段都有相应的隐藏输入。

复杂属性列表的MVC ModelState验证

使用

   [HttpPost]       
    public ActionResult CreateEnquiryOnly([Bind(Include="FirstName,LastName")]UserViewModel userviewmodel)
    {
        if(ModelState.IsValid)
        {       
        }
    }

如果您的请求视图模型包含指定视图不需要的属性或验证规则,则应为此创建一个新对象。

// New model, specific for request
public class UserRequestViewModel
{
    [Required(ErrorMessage="FirstName")]
    public string FirstName { get; set; }
    [Required(ErrorMessage = "LastName")]
    public string LastName { get; set; }
}
public ActionResult Index(UserRequestViewModel requestModel)
{
    //... do something
    // Get the values required to return to the view
    var responseModel = new UserViewModel();
    responseModel.DesiredUnits = new List<UnitViewModel>();
    // Return the response model
    return View(responseModel);
}

如果你这样做,任何为你的应用程序开发的人都会清楚,什么是可以接受的,可以发布到你的操作中。

或者,如果您决定不能为此创建整个新模型,请将验证转移到控制器操作中:

public ActionResult Index(UserViewModel requestResponseModel)
{
    // Perform validation
    for (var i = 0; i < requestResponseModel.DesiredUnits.Count(); i++)
    {
        var validationErrorKey = string.Format("DesiredUnits[{0}]", i);
        // Is the Name property empty?
        if (string.IsNullOrWhiteSpace(requestResponseModel.DesiredUnits[i].Name))
        {

            this.ModelState.AddModelError("Posted Name cannot be empty", validationErrorKey );
        }
    }
    if (this.ModelState.IsValid)
    {
        // There was a model validation error
    }
    //... do something
    // Return the response model
    return View(requestResponseModel);
}

作为最后的手段,你可以使用,但我不确定这是否会阻止字段的验证——你需要尝试一下:

public ActionResult Index([Bind(Exclude = "DesiredUnits")]UserViewModel requestResponseModel)
{
    // ... do something
}