【问题标题】:How to write an ASP.NET custom validator for a model defined in an external library如何为外部库中定义的模型编写 ASP.NET 自定义验证器
【发布时间】:2021-02-25 16:46:05
【问题描述】:

我正在尝试为我正在开发的 ASP.NET Core Web 应用程序编写自定义验证类。我找到了各种如何编写自定义客户端验证的示例,例如thisthis。这些都很清楚,对我来说很有意义。但是,我的问题是我的模型是在其他项目共享的 .NET 标准库中定义的。我无法访问在此库中创建自定义验证类所需的基类。

基本上,我需要确保model.PropertyA 永远不会大于model.PropertyB。我知道我可以编写一些 JavaScript 来实现这一点,但如果可能的话,我更愿意利用现有的 ASP.NET Core 验证技术。

如果可能的话,我宁愿避免任何第三方依赖来实现这一点。

【问题讨论】:

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


    【解决方案1】:

    你, 最好避免针对数据注释进行验证,因为您无法在所有情况下都访问它们,就像您描述的情况一样; 一个强大的包存在“FluentValidation” 您可以创建一个模型类并针对属性进行验证 示例:

    public class Person {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public int Age { get; set; }
    }
    

    完整文档:https://docs.fluentvalidation.net/en/latest/aspnet.html

    然后为您的命令添加一个验证器,如下例所示:

       public class CreatePersonCommandValidator : 
            AbstractValidator<CreatePersonCommand>
    {
        ....
    
        public CreateTodoListCommandValidator(IApplicationDbContext context)
        {
            _context = context;
    
            RuleFor(v => v.Name)
                .NotEmpty().WithMessage("Name is required.")
                .MaximumLength(200).WithMessage("Name must not exceed 200 characters.");
                 
            }...
          ....
         ..
    

    【讨论】:

    • 感谢您的回答。不幸的是,作为一般规则,我会尽可能避免第三方依赖。我认为对我来说最好的解决方案可能是在 JavaScript 中手动完成,除非有其他解决方案可用。无论如何,我都会支持你的答案。
    【解决方案2】:

    您可以构建一个类来扩展库中的类。并扩展IValidatableObject 来实现验证。

    Base 类来自图书馆。

       public class Base
        {
            public int PropertyA { get; set; }
            public int PropertyB { get; set; }
        }
    

    MyClass 是为验证而构建的。

    public class MyClass : Base, IValidatableObject
    {
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (PropertyA > PropertyB)
            {
                yield return new ValidationResult(
                    $"model.PropertyA {PropertyA} can't  greater than model.PropertyB ." );
            }
        }
    }
    

    测试代码:

    [HttpPost]
    public IActionResult Add([FromBody]MyClass myClass)
    {
        if (ModelState.IsValid)
        {
            RedirectToAction("Index");
        }
        return View();
    }
    

    测试结果:

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

    【讨论】:

    • 那么,如果我也想针对其他属性进行验证,但我不需要对它们进行自定义验证,该怎么办?由于验证存在于新的 MyClass 中,使用上面的示例,我如何将一个简单的 [Required] 属性添加到一个不太复杂的属性中,我只关心它是否为空?
    • 您是指来自Base 实体的其他属性吗?对不起,我的理解不佳,我对上面的描述感到困惑。我建议您可以更新问题或发布新线程来讨论它。
    • 我为错误的沟通道歉。我看到以全新的眼光看待您的示例,我将在 Validate() 方法中添加更多逻辑来解决此问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    相关资源
    最近更新 更多