【发布时间】:2017-10-11 18:01:00
【问题描述】:
在 MVC 中,当我们将模型发布到操作时,我们会执行以下操作以根据该模型的数据注释验证模型:
if (ModelState.IsValid)
如果我们将属性标记为 [Required],则 ModelState.IsValid 将验证该属性是否包含值。
我的问题:如何手动构建和运行自定义验证器?
附:我说的只是后端验证器。
【问题讨论】:
标签: c# asp.net-core asp.net-core-mvc
在 MVC 中,当我们将模型发布到操作时,我们会执行以下操作以根据该模型的数据注释验证模型:
if (ModelState.IsValid)
如果我们将属性标记为 [Required],则 ModelState.IsValid 将验证该属性是否包含值。
我的问题:如何手动构建和运行自定义验证器?
附:我说的只是后端验证器。
【问题讨论】:
标签: c# asp.net-core asp.net-core-mvc
在 .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。
【讨论】:
要在.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; }
}
这种方法是否会提供在控制器操作方法中使用“ModelState.IsValid”属性的机会?
是的! ModelState 对象将正确反映错误。
这种方法可以应用于模型类吗?还是只能与模型类属性一起使用?
我不知道这是否可以应用于班级级别。我知道您可以从ModelValidationContext 获取有关课程的信息:
context.Model:返回要验证的属性值context.Container:返回包含该属性的对象context.ActionContext:提供上下文数据并描述处理请求的动作方法context.ModelMetadata:详细描述正在验证的模型类按照 OP 中的要求,此验证属性不适用于客户端验证。
【讨论】: