如何在 IValidateOptions<T> 中触发模型验证执行? [英] How to trigger model validation inside IValidateOptions&lt;T&gt; implementation?

查看:29
本文介绍了如何在 IValidateOptions<T> 中触发模型验证执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 .Net 5 应用程序,想为我的配置添加验证器.鉴于此示例选项

I have a .Net 5 app and want to add validators for my configurations. Given this sample options

public sealed class DatabaseOptions
{
    public string ConnectionString { get; set; }
}

我目前使用此实现对其进行验证

I currently validate it with this implementation

public sealed class DatabaseOptionsValidator : IValidateOptions<DatabaseOptions>
{
    public ValidateOptionsResult Validate(string name, DatabaseOptions databaseOptions)
    {
        List<string> validationFailures = new List<string>();

        if (string.IsNullOrEmpty(databaseOptions.ConnectionString))
            validationFailures.Add($"{nameof(databaseOptions.ConnectionString)} is required.");

        // ...

        if (validationFailures.Any())
        {
            return ValidateOptionsResult.Fail(validationFailures);
        }

        return ValidateOptionsResult.Success;
    }
}

我想避免实施自己的验证检查和错误消息,因为我知道数据注释已经完成了工作.

I would like to avoid implementing my own validation checks and error messages since I know data annotations already get the job done.

我将选项模型修改为这个

I modified the options model to this

public sealed class DatabaseOptions
{
    [Required]
    [MinLength(9999999)] // for testing purposes
    public string ConnectionString { get; set; }
}

并希望找到触发模型验证的方法

and was hoping to find a way to trigger the model validation

public sealed class DatabaseOptionsValidator : IValidateOptions<DatabaseOptions>
{
    public ValidateOptionsResult Validate(string name, DatabaseOptions databaseOptions)
    {
        List<string> validationFailures = new List<string>();

        // trigger the model validation and add every error to the validationFailures list

        if (validationFailures.Any())
        {
            return ValidateOptionsResult.Fail(validationFailures);
        }

        return ValidateOptionsResult.Success;
    }
}

但不幸的是我无法这样做.调试器命中验证器,但如何在 Validate 方法中触发验证?

but unfortunately I wasn't able to do so. The debugger hits the validator but how can I trigger the validation inside the Validate method?

推荐答案

我使用了一种技术来验证我的 netcore 应用程序中的数据注释,不是使用 IValidateOptions,而是实现自定义验证器,并且将其注册为 PostConfigure.

There is a technique I use for validating data annotations in my netcore apps, not using IValidateOptions, but implementing a custom validator, and registering it as PostConfigure.

您可以在名称空间 System.ComponentModel.DataAnnotations 中找到有价值的资产.

You can find valuable assets in the namespace System.ComponentModel.DataAnnotations.

像这样:

    // Custom validator for data annotations
    public static class Validation {
        public static void ValidateDataAnotations<TOptions>(TOptions options) {
            var context = new ValidationContext(options);
            var results = new List<ValidationResult>();
            Validator.TryValidateObject(options, context, results, validateAllProperties: true);
            if (results.Any()) {
                var aggrErrors = string.Join(' ', results.Select(x => x.ErrorMessage));
                var count = results.Count;
                var configType = typeof(TOptions).Name;
                throw new ApplicationException($"Found {count} configuration error(s) in {configType}: {aggrErrors}");
            }
        }
    }

然后,您在组合根目录(可能是 Startup.cs)中注册此静态方法:

Then, you register this static method in you composition root (probably Startup.cs):

    public void ConfigureServices(IConfiguration configuration, IServiceCollection serviceCollection) {
        // (...)

        serviceCollection.Configure<DatabaseOptions>(configuration.GetSection(nameof(DatabaseOptions)));

        // invalid configuration values will break at this point
        serviceCollection.PostConfigure<DatabaseOptions>(Validation.ValidateDataAnotations);
    }

这篇关于如何在 IValidateOptions<T> 中触发模型验证执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆