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

时间:2017-10-11 18:01:00

标签: c# asp.net-core asp.net-core-mvc

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

if (ModelState.IsValid)

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

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

P.S。我只是在讨论后端验证器。

2 个答案:

答案 0 :(得分:16)

在.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;
    }
}

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

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

[ClassicMovie(1960)]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

这是另一个更简单的示例,用于确保值为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;
}

这是以相同的方式应用:

[EnforceTrue]
public bool ThisShouldBeTrue { get; set; }

编辑:根据要求提供前端代码:

<div asp-validation-summary="All" class="text-danger"></div>

选项包括All,ModelOnly或None。

答案 1 :(得分:7)

要在.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)
        };
    }
}

模型

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

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

    [Required]
    [ValidUrl]
    public string ProductThumbnailUrl { get; set; }
}
  

这种方法是否有机会与&#34; ModelState.IsValid&#34;控制器动作方法中的属性?

是的! ModelState对象将正确反映错误。

  

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

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

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

注意:

此验证属性不适用于客户端验证,如OP。

中所要求的那样