【问题标题】:Adding custom error message for model property为模型属性添加自定义错误消息
【发布时间】:2016-10-14 13:52:50
【问题描述】:

有没有一种方法可以覆盖控制器为模型属性引发的默认验证错误?例如,car.make 不能为 null,但如果该人拼写错误的汽车名称,我想抛出一个特定的错误。:

型号

public class Car
{
    public int ID { get; set; }
    [Required]
    public string Make { get; set; }
}

查看

<div class="form-group">
       @Html.EditorFor(model => model.Make, new { htmlAttributes = new { @class = "form-control" } })
       @Html.ValidationMessageFor(model => model.Make, "", new { @class = "text-danger" })
</div>

控制器

public ActionResult Create([Bind(Include = "Make,Model")] Car car)
{
    ModelState.AddModelError("Car.Make", "Check your spelling");
    return View(car);
}

【问题讨论】:

  • 不是.AddModelError("Car.Make", ...) 而是.AddModelError("Make", ...) - 您的模型不包含名为Car 的属性。但如果您只想从有效值中进行选择,请考虑使用 &lt;select&gt; 元素(或 jQuery 自动完成)

标签: c# asp.net-mvc forms validation


【解决方案1】:

只需要修改ModelState.AddModelError("Car.Make", "Check your spelling");方法就好了

public ActionResult Create([Bind(Include = "Make,Model")] Car car)
{
     if(//Your Condition upon which you want to model validation throw error) {
        ModelState.AddModelError("Make", "Check your spelling");
      }
     if (ModelState.IsValid) {
       //Rest of your logic 
     }
   return View(car);
 }

更好的方法是将验证逻辑排除在控制器之外。如果您想这样做,您需要根据您的验证逻辑创建自定义注释。要创建自定义注释,您需要创建新类并在您的类中实现 ValidationAttribute

 public class SpellingAttributes: ValidationAttribute  
 {
 } 

下一步您需要覆盖 IsValid() 并在其中编写验证逻辑

protected override ValidationResult IsValid(object value, ValidationContext validationContext)  
{  
    //validation logic 

   //If validation got success return ValidationResult.Success;
    return ValidationResult.Success;  
} 

并且在你的模型类中你可以直接使用这个注解

public class Car
{
     public int ID { get; set; }
     [Required]
     [Spelling(ErrorMessage ="Invalid Spelling")
     public string Make { get; set; }
}

有关如何在 MVC 中创建自定义注解的更多详细信息,您可以参考我的blog here,希望对您有所帮助。

【讨论】:

  • 我的表单在实际提交表单之前使用 ajax 检查用户为 car.make 提交的内容是否有效。为了验证用户提交的内容,我需要将表单值作为变量传递给 DataAnnotation。但是,我认为这是不可能的。读完这篇文章后。是这样吗? stackoverflow.com/questions/21680554/…
【解决方案2】:

我将实现自定义DataAnnotation 属性并将其用于Car.Make 属性验证。

这里有它的实现框架:

public class CheckSpellingAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        string stringValue = value as string;
        if (string.IsNullOrEmpty(stringValue) != false)
        {
            //your spelling validation logic here
            return isSpellingCorrect(stringValue );
        }
        return true;
   }
}

以后你可以像这样在你的模型上使用它:

public class Car
{
     public int ID { get; set; }

     [Required]
     [CheckSpelling(ErrorMessage = "Check your spelling")]
     public string Make { get; set; }
}

你的观点不会改变,行动会更简单

public ActionResult Create([Bind(Include = "Make,Model")] Car car)
{
    return View(car);
}

【讨论】:

    【解决方案3】:

    控制器中的 create 方法应该如下所示:

    public ActionResult Create([Bind(Include = "Make,Model")] Car car)
    {
        if(!checkSpelling(car.Make)) {
            ModelState.AddModelError("Make", "Check your spelling");
        }
        if (ModelState.IsValid) {
            //Save changes
        }
        return View(car);
    }
    

    您会注意到 ModelState.AddModelError(string key, string errorMessage) 方法的第一个参数 key 在您的情况下应该只是 "Make"。参考:MSDN

    无论如何,我建议实现类似于this example 的自定义ValidationAttribute

    【讨论】:

      【解决方案4】:
      public ActionResult Create([Bind(Include = "Make,Model")] Car car)
      {
          if (ModelState["Make"] == null)
          {
              var innerModelState = new ModelState();
              innerModelState.Errors.Add("Check your spelling");
              ModelState.Add(new KeyValuePair<string, System.Web.Mvc.ModelState>("Make", innerModelState));
          }
      
          return View(car);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-01
        • 2020-11-23
        • 2015-01-19
        • 2017-05-30
        • 1970-01-01
        • 1970-01-01
        • 2015-09-23
        • 1970-01-01
        相关资源
        最近更新 更多