Подтвердить что ты не робот

Как загрузить раздел appsetting.json в словарь в .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."
}

Есть ли способ загрузить эти данные в объект Dictionary MobileConfigInfo, а затем использовать шаблон IOptions для ввода MobileConfigInfo в контроллер?

4b9b3361

Ответ 1

Вы можете использовать Configuration.Bind(settings); в startup.cs классе

И ваш класс настроек будет похож на

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

Надеюсь, что это поможет!

Ответ 2

Перейдите в этот формат структуры:

"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);
});

Ответ 3

Для других, кто хочет преобразовать его в Словарь,

образец раздела внутри appsettings.json

"MailSettings": {
    "Server": "http://mail.mydomain.com"        
    "Port": "25",
    "From": "[email protected]"
 }

Следующий код следует поместить в файл Startup > 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.

Ответ 4

Я считаю, что вы можете использовать следующий код:

var config =  Configuration.GetSection("MobileConfigInfo").Get<Dictionary<string, string>>(); 

Ответ 5

Для простых (возможно, микросервисных) приложений вы можете просто добавить его как одиночный 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

Безусловно, самый простой способ - определить класс конфигурации для наследования от типа Dictionary, который вы хотите поддерживать.

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

Тогда ваша поддержка запуска и внедрения зависимостей будет точно такой же, как и для любого другого типа конфигурации.

Ответ 7

В качестве примера более сложного связывания в ASP.Net Core 2.1; Я обнаружил, что с помощью метода 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": "[email protected]",
                "Password": "password",
                "DefaultSender": "[email protected]"
            }
        }
    }
}

В эту структуру конфигурации:

[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; }
}

Ответ 8

Я использую способ ниже:

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;
}

Ответ 9

Единственное, что сработало для меня (ASP.NET Core 3.0), - это добавить следующее в метод ConfigureServices Startup.cs:

services.Configure<Dictionary<string, string>>(dict => Configuration.GetSection("MySectionName").GetChildren().ToList().ForEach(c => dict[c.Key] = c.Value));