欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ASP.NET MVC自定义验证逻辑1

程序员文章站 2022-07-08 10:38:39
...

1.自定义注解

假设要限制顾客输入姓氏中单词的数量,例如姓氏中单词的数量不等超过10个,并且还要让这种验证(限定一个string类型的最大单词数)重用。

所有的验证注解(如Required和Range)特性最终都派生自基类ValidationAttribute,它是个抽象类,在命名空间

System.ComponentModel.DataAnnotations

中定义。同样,自定义的验证逻辑也必须派生自ValidationAttribute的类。

为了实现这个验证逻辑,至少需要重写基类中提供的IsValid方法中的其中一个版本。重写IsValid方法时利用的ValidationContext参数,提供了很多可在IsValid返回发内部使用的信息,如模型类型、模型对象实例、用来验证属性的人性化显示名称以及其他有用信息。

public class MaxWordsAttribute : ValidationAttribute
{
  protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  {
    return ValidationResult.Success;
  }
}

IsValid方法中的第一个参数是要验证的对象的值。如果这个对象值是有效的,就可以返回一个成功的验证结果,但在判断它是由有效之前需要知道单词数的上限。要获得这一上限,可以通过向这个特性添加一个构造函数来要求顾客把最大单词数作为一个参数传递给它:

public class MaxWordsAttribute : ValidationAttribute
{
  private readonly int _maxWords;
  public MaxWordsAttribute(int maxWords)
  {
     _maxWords = maxWords;
  }
  protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  {
    return ValidationResult.Success;
  }
}

既然已经参数化了最大的单词数,下面就可以实现验证逻辑来捕获错误了:

public class MaxWordsAttribute : ValidationAttribute
{
  private readonly int _maxWords;
  public MaxWordsAttribute(int maxWords)
  {
     _maxWords = maxWords;
  }
  protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  {
    if(value != null)
    {
        var valueAsString = value.ToString();
        if(valueAsString.Split(' ').Length > _maxWords)
        {
           return new ValidationResult("Too many words!");
        }
        return ValidationResult.Success;
  }
}

上面代码中的问题在于硬编码的错误提示消息那行代码。使用数据注解的开发人员希望可以使用ValidationAttribute的ErrorMessage属性来自定义错误提示消息。同时还要与其他验证特性一样,提供一个默认的错误消息,并且还要利用验证的属性名称来生成错误提示信息:

public class MaxWordsAttribute : ValidationAttribute
{
  private readonly int _maxWords;
  public MaxWordsAttribute(int maxWords):base("{0}" has too many words)
  {
     _maxWords = maxWords;
  }
  protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  {
    if(value != null)
    {
        var valueAsString = value.ToString();
        if(valueAsString.Split(' ').Length > _maxWords)
        {
           var errorMessage = FormatErrorMessage(
                  validationContext.DisplayName);
           return new ValidationResult(errorMessage);
        }
        return ValidationResult.Success;
  }
}

前面 的代码做了两处改动:



首先,向基类的构造函数传递一个默认的错误提示信息。如果正在面向国际开发应用程序的话,就应该从一个资源文件中提取这个默认的错误提示信息。

注意:默认的错误提示信息中包含了一个参数占位符{0}。这个占位符之所以存在,是因为第二处改动,即调用继承的FormatErrorMessage方法会自动使用显示的属性名称来格式化这个字符串。

FormatErrorMessage可以确保我们使用合适的错误提示消息字符串(即使这个字符串存储在一个本地资源文件中)。这条代码语句需要传递name属性的值,这个值可以通过validationContext参数的DisplayName属性获得。

使用:[MaxWords(10, ErrorMessage="There are too many words in {0}")]