如何在.NET Core中将appsetting.json部分加载到Dictionary中?

时间:2017-03-16 22:59:42

标签: c# asp.net-core .net-core

我很熟悉将appsettings.json部分加载到.NET Core startup.cs中的强类型对象中。例如:

public class CustomSection 
{
   public int A {get;set;}
   public int B {get;set;}
}

//In Startup.cs
services.Configure<CustomSection>(Configuration.GetSection("CustomSection"));

//Inject an IOptions instance
public HomeController(IOptions<CustomSection> options) 
{
    var settings = options.Value;
}

我有一个appsettings.json部分,随着时间的推移,其键/值对的数量和名称会有所不同。因此,对类中的属性名称进行硬编码是不切实际的,因为新的键/值对需要在类中进行代码更改。一些键/值对的小样本:

"MobileConfigInfo": {
    "appointment-confirmed": "We've booked your appointment. See you soon!",
    "appointments-book": "New Appointment",
    "appointments-null": "We could not locate any upcoming appointments for you.",
    "availability-null": "Sorry, there are no available times on this date. Please try another."
}

有没有办法将这些数据加载到MobileConfigInfo Dictionary对象中,然后使用IOptions模式将MobileConfigInfo注入控制器?

11 个答案:

答案 0 :(得分:20)

您可以在Configuration.Bind(settings);

中使用startup.cs

您的设置类就像

public class AppSettings
{
    public Dictionary<string, string> MobileConfigInfo
    {
        get;
        set;
    }
}

希望它有所帮助!

答案 1 :(得分:20)

采用这种结构格式:

"MobileConfigInfo": {
    "Values": {
       "appointment-confirmed": "We've booked your appointment. See you soon!",
       "appointments-book": "New Appointment",
       "appointments-null": "We could not locate any upcoming appointments for you.",
       "availability-null": "Sorry, there are no available times on this date. Please try another."
 }
}

让您的设置类看起来像这样:

public class CustomSection 
{
   public Dictionary<string, string> Values {get;set;}
}

然后这样做

services.Configure<CustomSection>((settings) =>
{
     Configuration.GetSection("MobileConfigInfo").Bind(settings);
});

答案 2 :(得分:12)

对于想要将其转换为词典的其他人,

appsettings.json

中的

示例部分

"MailSettings": {
    "Server": "http://mail.mydomain.com"        
    "Port": "25",
    "From": "info@mydomain.com"
 }

以下代码应放在启动文件&gt; ConfigureServices方法:

public static Dictionary<string, object> MailSettings { get; private set; }

public void ConfigureServices(IServiceCollection services)
{
    //ConfigureServices code......

    MailSettings = 
        Configuration.GetSection("MailSettings").GetChildren()
        .Select(item => new KeyValuePair<string, string>(item.Key, item.Value))
        .ToDictionary(x => x.Key, x => x.Value);
}

现在您可以从以下任何地方访问字典:

string mailServer = Startup.MailSettings["Server"];

一个缺点是所有值都将作为字符串检索,如果您尝试任何其他类型,则该值将为null。

答案 3 :(得分:5)

我相信您可以使用以下代码:

Expanded

答案 4 :(得分:3)

您可以即时完成:

appsettings.json:
{
   "MobileConfigInfo": {
      "a": "x",
      "b": "y",
      "c": "z"
    }
}

代码中的某处:(不要忘记将 IConfiguration 依赖添加到类构造函数中)

var yourDictionary = _configuration.GetSection("MobileConfigInfo")
                .Get<IDictionary<string, string>>();

答案 5 :(得分:2)

对于简单(也许是微服务)应用程序,您只需将其添加为单个Dictionary<string, string>,然后将其注入任何需要的位置:

var mobileConfig = Configuration.GetSection("MobileConfigInfo")
                    .GetChildren().ToDictionary(x => x.Key, x => x.Value);

services.AddSingleton(mobileConfig);

用法:

public class MyDependantClass
{
    private readonly Dictionary<string, string> _mobileConfig;

    public MyDependantClass(Dictionary<string, string> mobileConfig)
    {
        _mobileConfig = mobileConfig;
    }

    // Use your mobile config here
}

答案 6 :(得分:2)

作为ASP.Net Core 2.1中更复杂绑定的示例;根据{{​​3}},我发现使用ConfigurationBuilder .Get<T>()方法更容易使用。

  

ASP.NET Core 1.1及更高版本可以使用Get,它适用于整个部分。获得比使用Bind更方便。

我在Startup方法中绑定了配置。

private Config Config { get; }

public Startup(IConfiguration Configuration)
{
    Config = Configuration.Get<Config>();
}

这会绑定appsettings文件:

{
    "ConnectionStrings": {
        "Accounts": "Server=localhost;Database=Accounts;Trusted_Connection=True;",
        "test": "Server=localhost;Database=test;Trusted_Connection=True;",
        "Client": "Server=localhost;Database={DYNAMICALLY_BOUND_CONTEXT};Trusted_Connection=True;",
        "Support": "Server=localhost;Database=Support;Trusted_Connection=True;"
    },
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "Default": "Debug",
            "System": "Information",
            "Microsoft": "Information"
        }
    },
    "Plugins": {
        "SMS": {
            "RouteMobile": {
                "Scheme": "https",
                "Host": "remote.host",
                "Port": 84567,
                "Path": "/bulksms",
                "Username": "username",
                "Password": "password",
                "Source": "CompanyName",
                "DeliveryReporting": true,
                "MessageType": "Unicode"
            }
        },
        "SMTP": {
            "GenericSmtp": {
                "Scheme": "https",
                "Host": "mail.host",
                "Port": 25,
                "EnableSsl": true,
                "Username": "smtpuser@mail.host",
                "Password": "password",
                "DefaultSender": "noreply@companyname.co.uk"
            }
        }
    }
}

进入此配置结构:

[DataContract]
public class Config
{
    [DataMember]
    public Dictionary<string, string> ConnectionStrings { get; set; }
    [DataMember]
    public PluginCollection Plugins { get; set; }
}

[DataContract]
public class PluginCollection
{
    [DataMember]
    public Dictionary<string, SmsConfiguration> Sms { get; set; }
    [DataMember]
    public Dictionary<string, EmailConfiguration> Smtp { get; set; }
}

[DataContract]
public class SmsConfiguration
{
    [DataMember]
    public string Scheme { get; set; }
    [DataMember]
    public string Host { get; set; }
    [DataMember]
    public int Port { get; set; }
    [DataMember]
    public string Path { get; set; }
    [DataMember]
    public string Username { get; set; }
    [DataMember]
    public string Password { get; set; }
    [DataMember]
    public string Source { get; set; }
    [DataMember]
    public bool DeliveryReporting { get; set; }
    [DataMember]
    public string Encoding { get; set; }
}

[DataContract]
public class EmailConfiguration
{
    [DataMember]
    public string Scheme { get; set; }
    [DataMember]
    public string Host { get; set; }
    [DataMember]
    public int Port { get; set; }
    [DataMember]
    public string Path { get; set; }
    [DataMember]
    public string Username { get; set; }
    [DataMember]
    public string Password { get; set; }
    [DataMember]
    public string DefaultSender { get; set; }
    [DataMember]
    public bool EnableSsl { get; set; }
}

答案 7 :(得分:2)

我使用以下方式:

appsettings.json:

  "services": {
      "user-service": "http://user-service:5000/",
      "app-service": "http://app-service:5000/"
  } 

startup.cs:

  services.Configure<Dictionary<string, string>>(Configuration.GetSection("services"));

用法:

private readonly Dictionary<string, string> _services;
public YourConstructor(IOptions<Dictionary<string, string>> servicesAccessor)
{
    _services = servicesAccessor.Value;
}

答案 8 :(得分:1)

对我来说唯一有效的方法(ASP.NET Core 3.0)是将以下内容添加到ConfigureServices的{​​{1}}方法中:

Startup.cs

答案 9 :(得分:1)

在.NET Core 3.1中,您可以执行以下操作...

appsettings.json:

{
  "myConfig": {
    "foo": "bar",
    "myMappings": {
      "key1": "value1",
      "key2": "value2"
    }
  }
}

配置模型

MyConfig.cs

public class MyConfig
{
    public string Foo { get; set; }
    public Dictionary<string, string> MyMappings { get; set; }
}

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyConfig>(configuration.GetSection("myConfig"));

使用以下选项进行分类:

public class OptionsUsingClass
{
    public OptionsUsingClass(IOptions<MyConfig> myConfigOptions)
    {
        // Be wary of nulls in real code.
        var myConfig = myConfigOptions.Value;

        // Examples with the above data.
        myConfig.Foo.Should().Be("bar");

        myConfig.MyMappings["key1"].Should().Be("value1");
        myConfig.MyMappings["key2"].Should().Be("value2");
    }

这就是我使用appsettings.json字典映射的方式。

答案 10 :(得分:0)

到目前为止,最简单的方法是定义要从要支持的Dictionary类型继承的配置类。

public class MobileConfigInfo:Dictionary<string, string>{
}

然后,您的启动和依赖项注入支持将与任何其他配置类型完全相同。