ASP.NET核心 - 自定义模型验证

use*_*430 14 c# asp.net-core-mvc asp.net-core

在MVC中,当我们将模型发布到操作时,我们执行以下操作以便针对该模型的数据注释验证模型:

if (ModelState.IsValid)
Run Code Online (Sandbox Code Playgroud)

如果我们将属性标记为[Required],则ModelState.IsValid将验证该属性是否包含值.

我的问题:如何手动构建和运行自定义验证器?

PS我只是在讨论后端验证器.

Kir*_*kin 24

在.NET Core中,您只需创建一个继承自的类ValidationAttribute.您可以在ASP.NET Core MVC Docs中查看完整的详细信息.

以下是直接从文档中获取的示例:

public class ClassicMovieAttribute : ValidationAttribute
{
    private int _year;

    public ClassicMovieAttribute(int Year)
    {
        _year = Year;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        Movie movie = (Movie)validationContext.ObjectInstance;

        if (movie.Genre == Genre.Classic && movie.ReleaseDate.Year > _year)
        {
            return new ValidationResult(GetErrorMessage());
        }

        return ValidationResult.Success;
    }
}
Run Code Online (Sandbox Code Playgroud)

我已根据您的问题中的要求调整了示例以排除客户端验证.

要使用此新属性(再次从文档中获取),您需要将其添加到相关字段:

[ClassicMovie(1960)]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
Run Code Online (Sandbox Code Playgroud)

这是确保值为的另一个更简单的示例true:

public class EnforceTrueAttribute : ValidationAttribute
{
    public EnforceTrueAttribute()
        : base("The {0} field must be true.") { }

    public override bool IsValid(object value) =>
        value is bool valueAsBool && valueAsBool;
}
Run Code Online (Sandbox Code Playgroud)

这是以相同的方式应用:

[EnforceTrue]
public bool ThisShouldBeTrue { get; set; }
Run Code Online (Sandbox Code Playgroud)


Dav*_*ang 10

要在其中创建自定义验证属性.Net Core,您需要继承IModelValidator并实现Validate方法.

自定义验证器

public class ValidUrlAttribute : Attribute, IModelValidator
{
    public string ErrorMessage { get; set; }

    public IEnumerable<ModelValidationResult> Validate(ModelValidationContext context)
    {
        var url = context.Model as string;
        if (url != null && Uri.IsWellFormedUriString(url, UriKind.Absolute))
        {
            return Enumerable.Empty<ModelValidationResult>();
        }

        return new List<ModelValidationResult>
        {
            new ModelValidationResult(context.ModelMetadata.PropertyName, ErrorMessage)
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

该模型

public class Product
{
    public int ProductId { get; set; }

    [Required]
    public string ProductName { get; set; }

    [Required]
    [ValidUrl]
    public string ProductThumbnailUrl { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这种方法是否有机会在控制器操作方法中使用"ModelState.IsValid"属性?

是! 该ModelState对象将正确反映错误.

这种方法可以应用于模型类吗?或者它只能与模型类属性一起使用?

我不知道这是否可以应用于班级.我知道您可以从中获取有关该课程的信息ModelValidationContext:

  • context.Model:返回要验证的属性值
  • context.Container:返回包含该属性的对象
  • context.ActionContext:提供上下文数据并描述处理请求的操作方法
  • context.ModelMetadata:描述正在详细验证的模型类

笔记:

根据OP中的要求,此验证属性不适用于客户端验证.

  • 我已经删除了此示例代码,因此我无法访问正在运行的代码并证明您可以为属性赋值。由于单一责任原则,我认为这不是一个好主意? (2认同)