模型即使包含值也显示无效

model showing invalid even after it contain values

我在 mvc 中有一个模型如下

public class person
{
  [Required(ErrorMessage = "Please enter First Name.")]
  public string first_name {get;set;}
  [Required(ErrorMessage = "Please enter last Name")]
  public string last_name {get;set;}
   [Required(ErrorMessage = "Please enter |DOB")]
  public DateTime DOB {get;set;}


}

post方法

[HttpPost]
public ActionResult save_person(person per)
{
if(per.first_name == null || per.first_name =="")
  per.first_name ="demo_first";
if(per.lastname == null || per.lastname =="")
  per.last_name ="demo_last";
if (ModelState.IsValid) //fails even assignment is done above
 {


  }

}

所以使用 if 条件我确保模型元素至少包含一些值,但即使在那之后 ModelState.IsValid 失败并返回视图说 first_name 并且需要 last_name

我们如何实现这个逻辑??

很不清楚为什么模型上的 first_namelast_name 属性用 Required 属性修饰,如果它们显然不是必需的。

这就是说,如果您想在控制器中更新某些模型 属性 的值,您可能需要确保也在 ModelState:

中更新它
if (per.first_name == null || per.first_name == "")
{
    per.first_name ="demo_first";
    ModelState.Remove("first_name");
    ModelState.SetModelValue("first_name", new ValueProviderResult(per.first_name, per.first_name, CultureInfo.InvariantCulture));
}

if (per.last_name == null || per.lastname == "")
{
    per.last_name ="demo_last";
    ModelState.Remove("last_name");
    ModelState.SetModelValue("last_name", new ValueProviderResult(per.last_name, per.last_name, CultureInfo.InvariantCulture));
}

if (ModelState.IsValid)
{
    ...
}

我只是想添加一些对实际文档的参考,以便为 OP 澄清为什么在方法中更改属性不能解决他的问题。

From the docs:

Handling Model State Errors

Model validation occurs prior to each controller action being invoked, and it is the action method’s responsibility to inspect ModelState.IsValid and react appropriately. In many cases, the appropriate reaction is to return some kind of error response, ideally detailing the reason why model validation failed.

这意味着,当调用 ActionResult 并设置 .IsValid 属性 时,验证已经发生。

根据您的评论:如果需要在不同的视图中使用相同的模型,但具有不同的验证要求,那么创建一个带有适当注释的新 ViewModel 是个好主意:

public class AnotherPersonViewModel {
    //no required attribute
    public string last_name {get; set;}
    //no required attribute
    public string first_name {get; set;}
    //... rest of attributes
}

在此之后,您始终可以将您的视图模型映射到您的实体模型或您当前正在做的任何事情。但是您可以避免使用不必要的代码使您的控制器混乱,以纠正架构中的错误。