前言
簡單整理一些配置的驗證。
正文
配置的驗證大概分為3類:
-
直接註冊驗證函式
-
實現IValidteOptions
-
使用Microsoft.Extensions.Options.DataAnnotations
直接註冊驗證函式
服務:
public class SelfService : ISelfService
{
IOptionsMonitor<SelfServiceOption> _options;
public SelfService(IOptionsMonitor<SelfServiceOption> options)
{
this._options = options;
_options.OnChange((selftServiceOptions) =>
{
Console.WriteLine("alter change:" + selftServiceOptions.Name);
});
}
public string ShowOptionName()
{
return _options.CurrentValue.Name;
}
}
註冊:
services.Configure<SelfServiceOption>(Configuration.GetSection("SelfService"), BinderOptions =>
{
BinderOptions.BindNonPublicProperties = true;
});
services.AddSingleton<ISelfService, SelfService>();
services.AddOptions<SelfServiceOption>().Validate(options =>
{
return options.Name != "zhangsan";
});
配置:
{
"SelfService": {
"name": "zhangsan"
}
}
測試:
[HttpGet]
public int GetService([FromServices]ISelfService selfService)
{
Console.WriteLine(selfService.ShowOptionName());
return 1;
}
結果:
使用Microsoft.Extensions.Options.DataAnnotations
services.AddOptions
加上這個函式ValidateDataAnnotations。
然後我們的配置類上加一些屬性之類的:
public class SelfServiceOption
{
[Required]
[StringLength(5)]
public string Name { get; set; }
}
因為zhangsan 這個字元超過了5。
結果:
實現IValidteOptions
書寫驗證函式:
public class SelfServiceValidateOptions : IValidateOptions<SelfServiceOption>
{
public ValidateOptionsResult Validate(string name, SelfServiceOption options)
{
if (options.Name.Length >5)
{
return ValidateOptionsResult.Fail("Name長度不能大於5");
}
else
{
return ValidateOptionsResult.Success;
}
}
}
註冊進去:
services.AddSingleton<IValidateOptions
結果:
![](https://img2020.cnblogs.com/blog/1289794/202106/1289794-20210606084403021-1632864116.png)
至於驗證的原理。
舉下面這個例子:
services.AddOptions<SelfServiceOption>().Validate(options =>
{
return options.Name != "zhangsan";
});
檢視Validate:
public virtual OptionsBuilder<TOptions> Validate(Func<TOptions, bool> validation)
{
return this.Validate(validation, "A validation error has occured.");
}
public virtual OptionsBuilder<TOptions> Validate(
Func<TOptions, bool> validation,
string failureMessage)
{
if (validation == null)
throw new ArgumentNullException(nameof (validation));
this.Services.AddSingleton<IValidateOptions<TOptions>>((IValidateOptions<TOptions>) new ValidateOptions<TOptions>(this.Name, validation, failureMessage));
return this;
}
就十二中也介紹了,在OptionFactory Create的函式中:
//這是_validations的型別
private readonly IEnumerable<IValidateOptions<TOptions>> _validations;
//下面是Create 函式部分:
if (_validations != null)
{
var failures = new List<string>();
foreach (var validate in _validations)
{
var result = validate.Validate(name, options);
if (result.Failed)
{
failures.AddRange(result.Failures);
}
}
if (failures.Count > 0)
{
throw new OptionsValidationException(name, typeof(TOptions), failures);
}
}
會把我們的驗證全部驗證執行一遍,然後給出全部的錯誤,所以如果報錯的時候,應該把錯誤看齊,不是隻顯示一個錯誤,因為可能不止一個錯誤。
結
以上只是個人整理,如有錯誤,望請指點。
下一節,日誌系統之戰地記者