web-dev-qa-db-fra.com

Comment charger la section appsetting.json dans Dictionary in .NET Core?

Je connais bien le chargement d’une section appsettings.json dans un objet fortement typé dans .NET Core startup.cs. Par exemple:

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

J'ai une section appsettings.json dont les paires clé/valeur varieront en nombre et en nom au fil du temps. Par conséquent, il n'est pas pratique de coder en dur les noms de propriété dans une classe car de nouvelles paires clé/valeur nécessiteraient un changement de code dans la classe. Un petit échantillon de quelques paires clé/valeur:

"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."
}

Existe-t-il un moyen de charger ces données dans un objet du dictionnaire MobileConfigInfo, puis d'utiliser le modèle IOptions pour injecter MobileConfigInfo dans un contrôleur?

15
ChrisP

Vous pouvez utiliser Configuration.Bind(settings); dans la classe startup.cs

Et votre classe de paramètres sera comme 

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

J'espère que ça aide!

16
Hung Cao

Aller avec ce format de structure:

"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."
 }
}

Faites en sorte que votre classe de réglage ressemble à ceci:

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

alors fais ceci

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

Pour les autres qui veulent le convertir en Dictionnaire

exemple de section à l'intérieur de appsettings.json

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

Le code suivant doit être placé dans la méthode Fichier de démarrage> 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);
}

Maintenant, vous pouvez accéder au dictionnaire depuis n'importe où:

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

Un inconvénient est que toutes les valeurs seront récupérées sous forme de chaînes. Si vous essayez un autre type, la valeur sera null.

11
Amro

Je crois que vous pouvez utiliser le code suivant:

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

Pour les applications simples (peut-être microservices), vous pouvez simplement l'ajouter en tant que singleton Dictionary<string, string>, puis l'injecter où vous en avez besoin:

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

services.AddSingleton(mobileConfig);

Et l'usage:

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

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

    // Use your mobile config here
}
2
ste-fu

Comme exemple de liaison plus complexe dans ASP.Net Core 2.1; J'ai trouvé qu'il était beaucoup plus facile de travailler avec la méthode ConfigurationBuilder.Get<T>(), selon the documention .

ASP.NET Core 1.1 et versions ultérieures peuvent utiliser Get, qui fonctionne avec des sections entières. Get peut être plus pratique que d'utiliser Bind.

J'ai lié la configuration dans ma méthode Startup.

private Config Config { get; }

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

Cela lie le fichier 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]"
            }
        }
    }
}

Dans cette structure de configuration:

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

De loin, la méthode la plus simple serait de définir votre classe de configuration pour hériter du type de dictionnaire que vous souhaitez prendre en charge.

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

Votre assistance d'injection de démarrage et de dépendance sera alors exactement la même que pour tout autre type de configuration.

0
Jeremy Lakeman

J'utilise le chemin ci-dessous:

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

Usage:

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