How to extract a list from appsettings.json in .net core

后端 未结 5 1893
耶瑟儿~
耶瑟儿~ 2020-12-24 00:13

I have an appsettings.json file which looks like this:

{
    \"someSetting\": {
        \"subSettings\": [
            \"one\",
            \"two\",
                 


        
5条回答
  •  暖寄归人
    2020-12-24 00:47

    In .NetCore this is what I did:

    Normal Setup:

    In your appsettings.json create a configuration section for your custom definitions:

        "IDP": [
        {
          "Server": "asdfsd",
          "Authority": "asdfasd",
          "Audience": "asdfadf"
        },
        {
          "Server": "aaaaaa",
          "Authority": "aaaaaa",
          "Audience": "aaaa"
        }
      ]
    

    Create a class to model the objects:

    public class IDP
    {
        public String Server { get; set; }
        public String Authority { get; set; }
        public String Audience { get; set; }
    
    }
    

    in your Startup -> ConfigureServices

    services.Configure>(Configuration.GetSection("IDP"));
    

    Note: if you need to immediately access your list within your ConfigureServices method you can use...

    var subSettings = Configuration.GetSection("IDP").Get>();
    

    Then in your controller something like this:

    Public class AccountController: Controller
    {
        private readonly IOptions> _IDPs;
        public AccountController(IOptions> IDPs)
        {
            _IDPs = IDPs;
        }
      ...
    }
    

    just as an example I used it elsewhere in the above controller like this:

           _IDPs.Value.ForEach(x => {
                // do something with x
            });
    

    Edge Case

    In the case that you need multiple configs but they can't be in an array and you have no idea how many sub-settings you will have at any one time. Use the following method.

    appsettings.json

    "IDP": {
        "0": {
          "Description": "idp01_test",
          "IDPServer": "https://intapi.somedomain.com/testing/idp01/v1.0",
          "IDPClient": "someapi",
          "Format": "IDP"
        },
        "1": {
          "Description": "idpb2c_test",
          "IDPServer": "https://intapi.somedomain.com/testing/idpb2c",
          "IDPClient": "api1",
          "Format": "IDP"
        },
        "2": {
          "Description": "MyApp",
          "Instance": "https://sts.windows.net/",
          "ClientId": "https://somedomain.com/12345678-5191-1111-bcdf-782d958de2b3",
          "Domain": "somedomain.com",
          "TenantId": "87654321-a10f-499f-9b5f-6de6ef439787",
          "Format": "AzureAD"
        }
      }
    

    Model

    public class IDP
    {
        public String Description { get; set; }
        public String IDPServer { get; set; }
        public String IDPClient { get; set; }
        public String Format { get; set; }
        public String Instance { get; set; }
        public String ClientId { get; set; }
        public String Domain { get; set; }
        public String TenantId { get; set; }
    }
    

    Create Extension for Expando Object

    public static class ExpandObjectExtension
        {
            public static TObject ToObject(this IDictionary someSource, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public)
                   where TObject : class, new()
            {
                Contract.Requires(someSource != null);
                TObject targetObject = new TObject();
                Type targetObjectType = typeof(TObject);
    
                // Go through all bound target object type properties...
                foreach (PropertyInfo property in
                            targetObjectType.GetProperties(bindingFlags))
                {
                    // ...and check that both the target type property name and its type matches
                    // its counterpart in the ExpandoObject
                    if (someSource.ContainsKey(property.Name)
                        && property.PropertyType == someSource[property.Name].GetType())
                    {
                        property.SetValue(targetObject, someSource[property.Name]);
                    }
                }
    
                return targetObject;
            }
        }
    

    ConfigureServices

    var subSettings = Configuration.GetSection("IDP").Get>();
    
    var idx = 0;
    foreach (var pair in subSettings)
    {
    
        IDP scheme = ((ExpandoObject)pair).ToObject();
        if (scheme.Format == "AzureAD")
        {
            // this is why I couldn't use an array, AddProtecedWebApi requires a path to a config section
            var section = $"IDP:{idx.ToString()}";
            services.AddProtectedWebApi(Configuration, section, scheme.Description);
            // ... do more stuff
            
        }
        idx++;
    }
    

提交回复
热议问题