在控制器中编辑后,ModelState不验证嵌套模型

Mau*_*loa 7 c# asp.net-mvc entity-framework

我有这两个嵌套的ViewModels:

public class FirstViewModel
{
    public SecondViewModel SecondViewModel { get; set; }
}

public class SecondViewModel
{
    [Range(1, 12)]
    public int month { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如果我放置month = 13;然后调用ModelState.IsValid(在控制器中),验证总是如此true.

编辑:

这是控制器:

public ActionResult Create()
{
    return PartialView(new FirstViewModel);    
}

public HttpStatusCodeResult Create (FirstViewModel viewModel){

    viewModel.SecondViewModel = new SecondViewModel();
    viewModel.SecondViewModel.month = 13;

    if (ModelState.IsValid)
    {
        return new HttpStatusCodeResult(200);
    }
    else
    {
        return new HttpStatusCodeResult(304);
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在对问题进行抽象,这些不是真正的变量.

小智 4

您的问题表明您在控制器中“调用 ModelState.Validate” 。没有这样的方法,所以我假设你的意思是if (ModelState.IsValid).

模型绑定过程的第一步是初始化方法的参数,在您的例子中是一个新的FirstViewModel. 然后,根据表单数据、路由值、查询字符串值等设置模型的值,并将与模型属性相关的任何验证错误添加到ModelState.

随后修改模型中属性的值不会影响ModelState,因此如果 的初始值month有效,则ModelState.IsValid无论设置如何都会返回 trueviewModel.SecondViewModel.month = 13;

如果你想重新验证你的模型,你需要使用TryUpdateModel它返回一个bool指示更新是否成功

public HttpStatusCodeResult Create (FirstViewModel viewModel)
{
  viewModel.SecondViewModel = new SecondViewModel();
  viewModel.SecondViewModel.month = 13;
  if (TryUpdateModel(viewModel)
  {
    return new HttpStatusCodeResult(200);
  }
  else
  {
    return new HttpStatusCodeResult(304);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 调用“TryUpdateModel”后,错误将添加到“ModelState”中。您可以考虑多种选项,例如 `varErrors = ModelState.Keys.Where(k => ModelState[k].Errors.Count > 0).Select(k => new { propertyName = k, errorMessage = ModelState[k].Errors[0].ErrorMessage });` 将为您提供所有有错误的属性名称以及与它们关联的第一个错误的集合,因此您可以使用 `return Json(errors);` 和然后在客户端循环遍历它们。 (2认同)