使用FluentValidation在Blazor中进行自定义验证

亚伦·拉姆福德

我正在尝试创建自定义复杂类型验证。我创建了一个具有三个子类的类型,每个子类都有一个自定义验证器。验证器仅使用默认值。一个特定的示例是,该金额应该允许为负数,但是无论我作何尝试,都只能允许> 0。任何帮助表示赞赏。

剃刀页

<TSValidator />

TSValidator.sc

public class TSValidator : ComponentBase
{
    [CascadingParameter] private EditContext CurrentEditContext { get; set; }

    protected override void OnInitialized()
    {
        if (CurrentEditContext == null)
        {
            throw new InvalidOperationException($"{nameof(TSValidator)} requires a cascading parameter of type {nameof(EditContext)}. For example, you can use {nameof(TSValidator)} inside an {nameof(EditForm)}");
        }

        CurrentEditContext.AddFluentValidation();
    }
}

延期

    public static EditContext AddFluentValidation(this EditContext editContext)
    {
        if (editContext == null)
        {
            throw new ArgumentNullException(nameof(editContext));
        }

        var messages = new ValidationMessageStore(editContext);

        editContext.OnValidationRequested += (sender, eventArgs) => ValidateModel((EditContext) sender, messages);

        editContext.OnFieldChanged += (sender, eventArgs) =>
            ValidateField(editContext, messages, eventArgs.FieldIdentifier);

        return editContext;
    }

    public static void ValidateModel(EditContext editContext, ValidationMessageStore store)
    {
        var validator = GetValidatorForModel(editContext.Model);
        var validationResults = validator.Validate(editContext.Model);

        store.Clear();
        foreach (var error in validationResults.Errors)
        {
            store.Add(editContext.Field(error.PropertyName), error.ErrorMessage);
        }

        editContext.NotifyValidationStateChanged();
    }

    public static void ValidateField(EditContext editContext, ValidationMessageStore store,
        in FieldIdentifier fieldIdentifier)
    {
        var properties = new[] {fieldIdentifier.FieldName};
        var context = new FluentValidation.ValidationContext(fieldIdentifier.Model, new FluentValidation.Internal.PropertyChain(), new MemberNameValidatorSelector(properties));
        var validator = GetValidatorForModel(fieldIdentifier.Model);
        var validationResults = validator.Validate(context);

        store.Clear();
        store.Add(fieldIdentifier, validationResults.Errors.Select(error => error.ErrorMessage));

        editContext.NotifyValidationStateChanged();
    }

    public static IValidator GetValidatorForModel(object model)
    {
        var abstractValidatorType = typeof(AbstractValidator<>).MakeGenericType(model.GetType());
        var modelValidatorType = Assembly.GetExecutingAssembly().GetTypes()
            .FirstOrDefault(t => t.IsSubclassOf(abstractValidatorType));
        var modelValidatorInstance = (IValidator) Activator.CreateInstance(modelValidatorType);

        return modelValidatorInstance;
    }

家长班

public class SubmissionActivity
{
    public Submission Submission { get; set; } = new Submission();
    public List<SalesActivitySubmission> SalesActivitySubmissions { get; set; } = new List<SalesActivitySubmission>();
    public RepActivitySubmission RepActivitySubmission { get; set; } = new RepActivitySubmission();

}

家长估价师

public class SubmissionActivityValidator : AbstractValidator<SubmissionActivity>
{
    public SubmissionActivityValidator()
    {
        RuleFor(s => s.RepActivitySubmission).SetValidator(new RepActivitySubmissionValidator());
        RuleForEach(s => s.SalesActivitySubmissions).SetValidator(new SalesActivitySubmissionValidator());
        RuleFor(s => s.Submission).SetValidator(new SubmissionValidator());
    }
}

儿童班

public class Submission
{
    [Key]
    public long SubmissionId { get; set; }
    public DateTime SubmissionDate { get; set; }
    public bool IsActive { get; set; }
    public int PropertyId { get; set; }
    public Property Property { get; set; }
    public DateTime CreatedOn { get; set; }
    public long CreatedBy { get; set; }
    public DateTime ModifiedOn { get; set; }
    public long ModifiedBy { get; set; }
}

public class SalesActivitySubmission
{
    [Key]
    public long SalesActivitySubmissionId { get; set; }
    public long? SubmissionId { get; set; }
    public Submission Submission { get; set; }
    public long? SellerId { get; set; }
    public User Seller { get; set; }
    public int? TicketHierarchyId { get; set; }
    public TicketHierarchy TicketHierarchy { get; set; }
    [Column(TypeName = "money")]
    [Range(-999999999999.99, 999999999999.99, ErrorMessage = "Please enter a positive amount of 999,999,999,999.99 or less.")]
    public decimal? Amount { get; set; }
    [Range(int.MinValue, int.MaxValue, ErrorMessage = "Please enter a valid positive number.")]
    public int? TicketSaleCount { get; set; }
    public DateTime CreatedOn { get; set; }
    public long CreatedBy { get; set; }
    public DateTime ModifiedOn { get; set; }
    public long ModifiedBy { get; set; }
}

public class RepActivitySubmission
{
    [Key]
    public int RepActivitySubmissionId { get; set; }
    public long SellerId { get; set; }
    public User Seller { get; set; }
    public long? SubmissionId { get; set; }
    public Submission Submission { get; set; }

    [Range(int.MinValue, int.MaxValue, ErrorMessage = "Please enter a valid positive number.")]
    public int? CompletedCalls { get; set; }

    [Range(int.MinValue, int.MaxValue, ErrorMessage = "Please enter a valid positive number.")]
    public int? Contacted { get; set; }

    [Range(int.MinValue, int.MaxValue, ErrorMessage = "Please enter a valid positive number.")]
    public int? Pitches { get; set; }

    [Range(int.MinValue, int.MaxValue, ErrorMessage = "Please enter a valid positive number.")]
    public int? Sales { get; set; }

    [Range(int.MinValue, int.MaxValue, ErrorMessage = "Please enter a valid positive number.")]
    public int? Referrals { get; set; }

    [Range(int.MinValue, int.MaxValue, ErrorMessage = "Please enter a valid positive number.")]
    public int? Appointments { get; set; }

    [Range(0, int.MaxValue, ErrorMessage = "Please enter a valid positive number.")]
    public int? HoursWorked { get; set; }

    [Range(0, int.MaxValue, ErrorMessage = "Please enter a valid positive number.")]
    public int? OvertimeHours { get; set; }

    [Range(0, int.MaxValue, ErrorMessage = "Please enter a valid positive number.")]
    public int? PTOHours { get; set; }

    [Column(TypeName = "money")]
    [Range(-999999999999.99, 999999999999.99, ErrorMessage = "Please enter a positive amount of 999,999,999.99 or less.")]
    public decimal? PropExpense { get; set; }
    public DateTime CreatedOn { get; set; }
    public long CreatedBy { get; set; }
    public DateTime ModifiedOn { get; set; }
    public long ModifiedBy { get; set; }
}

儿童验证器

public class SubmissionValidator : AbstractValidator<Submission>
{
    public SubmissionValidator()
    {
        RuleFor(s => s.SubmissionDate).NotEmpty().NotNull();
    }
}

public class SalesActivitySubmissionValidator : AbstractValidator<SalesActivitySubmission>
{
    public SalesActivitySubmissionValidator()
    {
        RuleFor(s => s.SalesActivitySubmissionId).NotNull().WithMessage("SalesActivitySubmissionId cannot be null");
        RuleFor(s => s.SubmissionId).NotNull().WithMessage("SubmissionId cannot be null.");
        RuleFor(s => s.SellerId).NotNull().WithMessage("SellerId cannot be null");
        RuleFor(s => s.TicketHierarchyId).NotNull().WithMessage("TicketHierarchyId cannot be null.");
        RuleFor(s => s.Amount).InclusiveBetween(0, 999999999999)
            .WithMessage("Amount must be within 0 and 999999999999, inclusively.");
        RuleFor(s => s.TicketSaleCount).GreaterThan(-1).LessThan(int.MaxValue)
            .WithMessage($"TicketSaleCount must be null or between 0 and {int.MaxValue} inclusively.");

    }
}

public class RepActivitySubmissionValidator : AbstractValidator<RepActivitySubmission>
{
    public RepActivitySubmissionValidator()
    {
        RuleFor(r => r.SellerId).NotNull().WithMessage("SellerId cannot be null.");
        RuleFor(r => r.SubmissionId).NotNull().WithMessage("SubmissionId cannot be null.");
        RuleFor(r => r.CompletedCalls).GreaterThanOrEqualTo(0).LessThanOrEqualTo(int.MaxValue)
            .WithMessage($"CompletedCalls must be between 0 and {int.MaxValue} inclusively");
        RuleFor(r => r.Contacted).GreaterThanOrEqualTo(0).LessThanOrEqualTo(int.MaxValue)
            .WithMessage($"Contacted must be between 0 and {int.MaxValue} inclusively");
        RuleFor(r => r.Pitches).GreaterThanOrEqualTo(0).LessThanOrEqualTo(int.MaxValue)
            .WithMessage($"Pitches must be between 0 and {int.MaxValue} inclusively");
        RuleFor(r => r.Sales).GreaterThanOrEqualTo(0).LessThanOrEqualTo(int.MaxValue)
            .WithMessage($"Sales must be between 0 and {int.MaxValue} inclusively");
        RuleFor(r => r.Referrals).GreaterThanOrEqualTo(0).LessThanOrEqualTo(int.MaxValue)
            .WithMessage($"Referrals must be between 0 and {int.MaxValue} inclusively");
        RuleFor(r => r.Appointments).GreaterThanOrEqualTo(0).LessThanOrEqualTo(int.MaxValue)
            .WithMessage($"Appointed must be between 0 and {int.MaxValue} inclusively");
        RuleFor(r => r.HoursWorked).GreaterThanOrEqualTo(0).LessThanOrEqualTo(int.MaxValue)
            .WithMessage($"HoursWorked must be between 0 and {int.MaxValue} inclusively");
        RuleFor(r => r.OvertimeHours).GreaterThanOrEqualTo(0).LessThanOrEqualTo(int.MaxValue)
            .WithMessage($"OvertimeHours must be between 0 and {int.MaxValue} inclusively");
        RuleFor(r => r.PTOHours).GreaterThanOrEqualTo(0).LessThanOrEqualTo(int.MaxValue)
            .WithMessage($"PTOHours must be between 0 and {int.MaxValue} inclusively");
        RuleFor(r => r.PropExpense).GreaterThanOrEqualTo(0).LessThan(1000000000000)
            .WithMessage("PropExpense must be between 0 and 999999999999.99.");
    }
}
g

它与允许负数的范围验证数据属性和不允许负数的fluentvalidation规则有关系吗?似乎您使用不同的验证提供程序两次为同一属性指定了验证规则,而每个提供程序指定的规则是不同的。

例如,

一个具体的示例是,该金额应该允许为负数,但是无论我尝试如何,它都只能允许> 0

public class SalesActivitySubmission
{
    ...

    [Column(TypeName = "money")]
    [Range(-999999999999.99, 999999999999.99, ErrorMessage = "Please enter a positive amount of 999,999,999,999.99 or less.")]
    public decimal? Amount { get; set; }

    ...
}
public class SalesActivitySubmissionValidator : AbstractValidator<SalesActivitySubmission>
{
    public SalesActivitySubmissionValidator()
    {
        ...

        RuleFor(s => s.Amount).InclusiveBetween(0, 999999999999)
            .WithMessage("Amount must be within 0 and 999999999999, inclusively.");

        ...
    }
}

通常,在使用fluentvalidation时不指定数据属性-如果可能,应该为验证提供单一的真实来源。

在ASP.NET Core中,fluentvalidation先于其他验证提供程序执行。在这种情况下,内置提供者将没有机会测试范围验证数据属性的负值,因为fluentvalidation已经测试了该属性并返回了验证失败。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

FluentValidation自定义验证问题

来自分类Dev

在自定义视图助手中进行验证

来自分类Dev

如何在语义UI中进行自定义验证?

来自分类Dev

在Mule ESB中进行自定义验证

来自分类Dev

在自定义视图助手中进行验证

来自分类Dev

在FluentValidation中对每个自定义规则进行客户端验证的最佳方法

来自分类Dev

使用AngularJs在ngTable中进行自定义排序

来自分类Dev

使用Python在Maya中进行简单的自定义UI

来自分类Dev

使用AngularJs在ngTable中进行自定义排序

来自分类Dev

无法在自定义Laravel测试环境中进行身份验证(代码接收)

来自分类Dev

用于在nesjts中进行验证的自定义装饰器-在服务层上

来自分类Dev

如何在Lombok项目设置器中进行自定义验证

来自分类Dev

无法在自定义Laravel测试环境中进行身份验证(代码接收)

来自分类Dev

如何在 Laravel 中进行自定义身份验证查询

来自分类Dev

在环回中使用数组进行自定义验证

来自分类Dev

使用自定义指令与angularjs进行验证

来自分类Dev

使用Keycloak进行自定义身份验证

来自分类Dev

使用joi进行自定义配置模块验证

来自分类Dev

使用$ {protocol}进行JavaScript RegExp自定义URL验证

来自分类Dev

使用自定义指令与angularjs进行验证

来自分类Dev

使用JavaEE对SOAP进行自定义身份验证

来自分类Dev

在环回中使用数组进行自定义验证

来自分类Dev

使用MVC进行自定义身份验证

来自分类Dev

使用$ .each()进行自定义JQuery验证

来自分类Dev

使用插件对 URL 进行 JQuery 验证需要自定义

来自分类Dev

使用异步服务进行角度自定义验证

来自分类Dev

如何使用使用两列的自定义函数在R中进行聚合

来自分类Dev

使用TailwindCSS和Typography插件,如何允许使用类在.prose中进行自定义?

来自分类Dev

如何使用使用两列的自定义函数在R中进行聚合

Related 相关文章

  1. 1

    FluentValidation自定义验证问题

  2. 2

    在自定义视图助手中进行验证

  3. 3

    如何在语义UI中进行自定义验证?

  4. 4

    在Mule ESB中进行自定义验证

  5. 5

    在自定义视图助手中进行验证

  6. 6

    在FluentValidation中对每个自定义规则进行客户端验证的最佳方法

  7. 7

    使用AngularJs在ngTable中进行自定义排序

  8. 8

    使用Python在Maya中进行简单的自定义UI

  9. 9

    使用AngularJs在ngTable中进行自定义排序

  10. 10

    无法在自定义Laravel测试环境中进行身份验证(代码接收)

  11. 11

    用于在nesjts中进行验证的自定义装饰器-在服务层上

  12. 12

    如何在Lombok项目设置器中进行自定义验证

  13. 13

    无法在自定义Laravel测试环境中进行身份验证(代码接收)

  14. 14

    如何在 Laravel 中进行自定义身份验证查询

  15. 15

    在环回中使用数组进行自定义验证

  16. 16

    使用自定义指令与angularjs进行验证

  17. 17

    使用Keycloak进行自定义身份验证

  18. 18

    使用joi进行自定义配置模块验证

  19. 19

    使用$ {protocol}进行JavaScript RegExp自定义URL验证

  20. 20

    使用自定义指令与angularjs进行验证

  21. 21

    使用JavaEE对SOAP进行自定义身份验证

  22. 22

    在环回中使用数组进行自定义验证

  23. 23

    使用MVC进行自定义身份验证

  24. 24

    使用$ .each()进行自定义JQuery验证

  25. 25

    使用插件对 URL 进行 JQuery 验证需要自定义

  26. 26

    使用异步服务进行角度自定义验证

  27. 27

    如何使用使用两列的自定义函数在R中进行聚合

  28. 28

    使用TailwindCSS和Typography插件,如何允许使用类在.prose中进行自定义?

  29. 29

    如何使用使用两列的自定义函数在R中进行聚合

热门标签

归档