如何在 IValidateOptions<T> 中触发模型验证执行? [英] How to trigger model validation inside IValidateOptions<T> implementation?
问题描述
我有一个 .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屋!