How to Use Configuration with ValidateDataAnnotations

后端 未结 2 464
悲&欢浪女
悲&欢浪女 2021-01-21 05:01

I\'ve read the Microsoft documentation of fundamentals for Options and Configuration, but still can\'t find the right way to extract configuration into an object while validatin

2条回答
  •  伪装坚强ぢ
    2021-01-21 05:41

    You can try validating the class yourself in start up before adding it to service collection.

    Startup

    var settings = Configuration.GetSection("Email").Get();
    
    //validate
    var validationResults = new List();
    var validationContext = new ValidationContext(settings, serviceProvider: null, items: null);
    if (!Validator.TryValidateObject(settings, validationContext, validationResults, 
            validateAllProperties: true)) {
        //...Fail early
        //will have the validation results in the list
    }
    
    services.AddSingleton(settings);
    

    That way you are not coupled to IOptions and you also allow your code to fail early and you can explicitly inject the dependency where needed.

    You could package the validation up into your own extension method like

    public static T GetValid(this IConfiguration configuration) {
        var obj = configuration.Get();    
        //validate
         Validator.ValidateObject(obj, new ValidationContext(obj), true);    
        return obj;
    }
    

    for calls like

    EmailConfig emailSection = Configuration.GetSection("Email").GetValid();
    services.AddSingleton(emailSection);
    

    Internally, ValidateDataAnnotations is basically doing the same thing.

    /// 
    /// Validates a specific named options instance (or all when name is null).
    /// 
    /// The name of the options instance being validated.
    /// The options instance.
    /// The  result.
    public ValidateOptionsResult Validate(string name, TOptions options)
    {
        // Null name is used to configure all named options.
        if (Name == null || name == Name)
        {
            var validationResults = new List();
            if (Validator.TryValidateObject(options,
                new ValidationContext(options, serviceProvider: null, items: null), 
                validationResults, 
                validateAllProperties: true))
            {
                return ValidateOptionsResult.Success;
            }
    
            return ValidateOptionsResult.Fail(String.Join(Environment.NewLine,
                validationResults.Select(r => "DataAnnotation validation failed for members " +
                    String.Join(", ", r.MemberNames) +
                    " with the error '" + r.ErrorMessage + "'.")));
        }
    
        // Ignored if not validating this instance.
        return ValidateOptionsResult.Skip;
    }
    

    Source Code

提交回复
热议问题