前言

簡單整理一些配置的驗證。

正文

配置的驗證大概分為3類:

  1. 直接註冊驗證函式

  2. 實現IValidteOptions

  3. 使用Microsoft.Extensions.Options.DataAnnotations

直接註冊驗證函式

服務:

  1. public class SelfService : ISelfService
  2. {
  3. IOptionsMonitor<SelfServiceOption> _options;
  4. public SelfService(IOptionsMonitor<SelfServiceOption> options)
  5. {
  6. this._options = options;
  7. _options.OnChange((selftServiceOptions) =>
  8. {
  9. Console.WriteLine("alter change:" + selftServiceOptions.Name);
  10. });
  11. }
  12. public string ShowOptionName()
  13. {
  14. return _options.CurrentValue.Name;
  15. }
  16. }

註冊:

  1. services.Configure<SelfServiceOption>(Configuration.GetSection("SelfService"), BinderOptions =>
  2. {
  3. BinderOptions.BindNonPublicProperties = true;
  4. });
  5. services.AddSingleton<ISelfService, SelfService>();
  6. services.AddOptions<SelfServiceOption>().Validate(options =>
  7. {
  8. return options.Name != "zhangsan";
  9. });

配置:

  1. {
  2. "SelfService": {
  3. "name": "zhangsan"
  4. }
  5. }

測試:

  1. [HttpGet]
  2. public int GetService([FromServices]ISelfService selfService)
  3. {
  4. Console.WriteLine(selfService.ShowOptionName());
  5. return 1;
  6. }

結果:

使用Microsoft.Extensions.Options.DataAnnotations

services.AddOptions().ValidateDataAnnotations();

加上這個函式ValidateDataAnnotations。

然後我們的配置類上加一些屬性之類的:

  1. public class SelfServiceOption
  2. {
  3. [Required]
  4. [StringLength(5)]
  5. public string Name { get; set; }
  6. }

因為zhangsan 這個字元超過了5。

結果:

實現IValidteOptions

書寫驗證函式:

  1. public class SelfServiceValidateOptions : IValidateOptions<SelfServiceOption>
  2. {
  3. public ValidateOptionsResult Validate(string name, SelfServiceOption options)
  4. {
  5. if (options.Name.Length >5)
  6. {
  7. return ValidateOptionsResult.Fail("Name長度不能大於5");
  8. }
  9. else
  10. {
  11. return ValidateOptionsResult.Success;
  12. }
  13. }
  14. }

註冊進去:

services.AddSingleton<IValidateOptions,SelfServiceValidateOptions>();

結果:

  1. ![](https://img2020.cnblogs.com/blog/1289794/202106/1289794-20210606084403021-1632864116.png)

至於驗證的原理。

舉下面這個例子:

  1. services.AddOptions<SelfServiceOption>().Validate(options =>
  2. {
  3. return options.Name != "zhangsan";
  4. });

檢視Validate:

  1. public virtual OptionsBuilder<TOptions> Validate(Func<TOptions, bool> validation)
  2. {
  3. return this.Validate(validation, "A validation error has occured.");
  4. }
  5. public virtual OptionsBuilder<TOptions> Validate(
  6. Func<TOptions, bool> validation,
  7. string failureMessage)
  8. {
  9. if (validation == null)
  10. throw new ArgumentNullException(nameof (validation));
  11. this.Services.AddSingleton<IValidateOptions<TOptions>>((IValidateOptions<TOptions>) new ValidateOptions<TOptions>(this.Name, validation, failureMessage));
  12. return this;
  13. }

就十二中也介紹了,在OptionFactory Create的函式中:

  1. //這是_validations的型別
  2. private readonly IEnumerable<IValidateOptions<TOptions>> _validations;
  3. //下面是Create 函式部分:
  4. if (_validations != null)
  5. {
  6. var failures = new List<string>();
  7. foreach (var validate in _validations)
  8. {
  9. var result = validate.Validate(name, options);
  10. if (result.Failed)
  11. {
  12. failures.AddRange(result.Failures);
  13. }
  14. }
  15. if (failures.Count > 0)
  16. {
  17. throw new OptionsValidationException(name, typeof(TOptions), failures);
  18. }
  19. }

會把我們的驗證全部驗證執行一遍,然後給出全部的錯誤,所以如果報錯的時候,應該把錯誤看齊,不是隻顯示一個錯誤,因為可能不止一個錯誤。

以上只是個人整理,如有錯誤,望請指點。

下一節,日誌系統之戰地記者