264 votes

Obtenir une valeur de appsettings.json en .net core

Je ne sais pas ce qui m'échappe, mais je ne parviens pas à obtenir les valeurs de mon appsettings.json dans mon application .net core. J'ai mes appsettings.json comme :

{
    "AppSettings": {
        "Version": "One"
    }
}

Démarrage :

public class Startup
{
    private IConfigurationRoot _configuration;
    public Startup(IHostingEnvironment env)
    {
        _configuration = new ConfigurationBuilder()
    }
    public void ConfigureServices(IServiceCollection services)
    {
      //Here I setup to read appsettings        
      services.Configure<AppSettings>(_configuration.GetSection("AppSettings"));
    }
}

Modèle :

public class AppSettings
{
    public string Version{ get; set; }
}

Contrôleur :

public class HomeController : Controller
{
    private readonly AppSettings _mySettings;

    public HomeController(IOptions<AppSettings> settings)
    {
        //This is always null
        _mySettings = settings.Value;
    }
}

_mySettings est toujours nul. Y a-t-il quelque chose qui m'échappe ici ?

3 votes

S'il vous plaît lire la documentation sur la façon d'utiliser la configuration. Vous avez mal défini la configuration dans votre classe de démarrage.

1 votes

Cela peut être encore simplifié en utilisant simplement l'injection de dépendances de IConfiguration. Ce qui est expliqué ici coding-issues.com/2018/10/

4 votes

Le fait qu'il y ait autant de réponses très différentes à cette question souligne le problème. Je me demande presque s'il n'est pas plus simple de lire le fichier de paramètres et de le désérialiser vers un objet créé avec un générateur de classe json -> c# en ligne. Avoir des paramètres qui ne sont pas fortement typés me semble primitif.

371voto

David Liang Points 4863

Merci @Kirk de m'avoir signalé que je ne devais pas supposer qu'il s'agissait de .NET Core 2.0 !

Programme et classe de démarrage

.NET Core 2.x

Vous n'avez pas besoin de nouvelles IConfiguration dans le Startup constructeur. Son implémentation sera injectée par le système DI.

// Program.cs
public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();            
}

// Startup.cs
public class Startup
{
    public IHostingEnvironment HostingEnvironment { get; private set; }
    public IConfiguration Configuration { get; private set; }

    public Startup(IConfiguration configuration, IHostingEnvironment env)
    {
        this.HostingEnvironment = env;
        this.Configuration = configuration;
    }
}

.NET Core 1.x

Vous devez dire Startup pour charger les fichiers appsettings.

// Program.cs
public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .Build();

        host.Run();
    }
}

//Startup.cs
public class Startup
{
    public IConfigurationRoot Configuration { get; private set; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        this.Configuration = builder.Build();
    }
    ...
}

Obtenir des valeurs

Il existe de nombreuses façons d'obtenir la valeur que vous avez configurée dans les paramètres de l'application :

  • Une façon simple d'utiliser ConfigurationBuilder.GetValue<T>
  • Utilisation de Motif des options

Disons que votre appsettings.json ressemble à ça :

{
    "ConnectionStrings": {
        ...
    },
    "AppIdentitySettings": {
        "User": {
            "RequireUniqueEmail": true
        },
        "Password": {
            "RequiredLength": 6,
            "RequireLowercase": true,
            "RequireUppercase": true,
            "RequireDigit": true,
            "RequireNonAlphanumeric": true
        },
        "Lockout": {
            "AllowedForNewUsers": true,
            "DefaultLockoutTimeSpanInMins": 30,
            "MaxFailedAccessAttempts": 5
        }
    },
    "Recaptcha": { 
        ...
    },
    ...
}

Une méthode simple

Vous pouvez injecter l'ensemble de la configuration dans le constructeur de votre contrôleur/classe (par le biais de l'option IConfiguration ) et obtenir la valeur que vous voulez avec une clé spécifiée :

public class AccountController : Controller
{
    private readonly IConfiguration _config;

    public AccountController(IConfiguration config)
    {
        _config = config;
    }

    [AllowAnonymous]
    public IActionResult ResetPassword(int userId, string code)
    {
        var vm = new ResetPasswordViewModel
        {
            PasswordRequiredLength = _config.GetValue<int>(
                "AppIdentitySettings:Password:RequiredLength"),
            RequireUppercase = _config.GetValue<bool>(
                "AppIdentitySettings:Password:RequireUppercase")
        };

        return View(vm);
    }
}

Motif des options

Le site ConfigurationBuilder.GetValue<T> fonctionne très bien si vous n'avez besoin que d'une ou deux valeurs des paramètres de l'application. Mais si vous souhaitez obtenir plusieurs valeurs à partir des paramètres de l'application, ou si vous ne voulez pas coder en dur ces chaînes de caractères à plusieurs endroits, il peut être plus facile d'utiliser la méthode suivante Motif des options . Le modèle des options utilise des classes pour représenter la hiérarchie/structure.

Pour utiliser le modèle d'options :

  1. Définir des classes pour représenter la structure
  2. Enregistrer l'instance de configuration contre laquelle ces classes se lient.
  3. Injecter IOptions<T> dans le constructeur du contrôleur/classe sur lequel vous voulez obtenir des valeurs.

1. Définir des classes de configuration pour représenter la structure

Vous pouvez définir des classes avec des propriétés qui doivent correspondre exactement les clés dans les paramètres de votre application. Le nom de la classe ne doit pas nécessairement correspondre au nom de la section dans les paramètres de l'application :

public class AppIdentitySettings
{
    public UserSettings User { get; set; }
    public PasswordSettings Password { get; set; }
    public LockoutSettings Lockout { get; set; }
}

public class UserSettings
{
    public bool RequireUniqueEmail { get; set; }
}

public class PasswordSettings
{
    public int RequiredLength { get; set; }
    public bool RequireLowercase { get; set; }
    public bool RequireUppercase { get; set; }
    public bool RequireDigit { get; set; }
    public bool RequireNonAlphanumeric { get; set; }
}

public class LockoutSettings
{
    public bool AllowedForNewUsers { get; set; }
    public int DefaultLockoutTimeSpanInMins { get; set; }
    public int MaxFailedAccessAttempts { get; set; }
}

2. Enregistrez l'instance de configuration

Et ensuite, vous devez enregistrer cette instance de configuration dans le fichier ConfigureServices() dans le démarrage :

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
...

namespace DL.SO.UI.Web
{
    public class Startup
    {
        ...
        public void ConfigureServices(IServiceCollection services)
        {
            ...
            var identitySettingsSection = 
                _configuration.GetSection("AppIdentitySettings");
            services.Configure<AppIdentitySettings>(identitySettingsSection);
            ...
        }
        ...
    }
}

3. Injecter des IOptions

Enfin, sur le contrôleur/classe où vous voulez récupérer les valeurs, vous devez injecter IOptions<AppIdentitySettings> par le biais du constructeur :

public class AccountController : Controller
{
    private readonly AppIdentitySettings _appIdentitySettings;

    public AccountController(IOptions<AppIdentitySettings> appIdentitySettingsAccessor)
    {
        _appIdentitySettings = appIdentitySettingsAccessor.Value;
    }

    [AllowAnonymous]
    public IActionResult ResetPassword(int userId, string code)
    {
        var vm = new ResetPasswordViewModel
        {
            PasswordRequiredLength = _appIdentitySettings.Password.RequiredLength,
            RequireUppercase = _appIdentitySettings.Password.RequireUppercase
        };

        return View(vm);
    }
}

0 votes

Comment puis-je accéder aux valeurs de la classe qui contient mes données ?

0 votes

@LukasHieronimusAdler : Voir Controller section de l'échantillon dans la question originale ?? Accédez à la valeur en faisant IOptions<AppSettings> settings et settings.Value ? ?

0 votes

@DavidLiang si je modifie manuellement le fichier appsettings.json pendant l'exécution, mon objet IOptions<AppSettings> settings ne reçoit pas les valeurs modifiées. Quel est le problème ? Si j'ajoute ceci : .AddJsonFile("appsettings.json", optional : false, reloadOnChange : true) Pour moi, il devrait se recharger lors d'un changement externe, n'est-ce pas ?

63voto

shajji Points 511

Il suffit de créer un fichier AnyName.cs et de coller le code suivant.

using System;
using System.IO;
using Microsoft.Extensions.Configuration;

namespace Custom
{
    static class ConfigurationManager
    {
        public static IConfiguration AppSetting { get; }
        static ConfigurationManager()
        {
            AppSetting = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("YouAppSettingFile.json")
                    .Build();
        }
    }
}

Vous devez remplacer le nom du fichier YouAppSettingFile.json par votre nom de fichier.
Votre fichier .json devrait ressembler à ce qui suit.

{
    "GrandParent_Key" : {
        "Parent_Key" : {
            "Child_Key" : "value1"
        }
    },
    "Parent_Key" : {
        "Child_Key" : "value2"
    },
    "Child_Key" : "value3"
}

Maintenant vous pouvez l'utiliser.
N'oubliez pas de Ajouter une référence dans votre classe où vous voulez l'utiliser.

using Custom;

Code pour récupérer la valeur.

string value1 = ConfigurationManager.AppSetting["GrandParent_Key:Parent_Key:Child_Key"];
string value2 = ConfigurationManager.AppSetting["Parent_Key:Child_Key"];
string value3 = ConfigurationManager.AppSetting["Child_Key"];

6 votes

Ne l'utilisez pas en production. Cette approche est à l'origine de fuites de mémoire dans notre api web. Si vous utilisez netcore, vous pouvez injecter IConfiguration littéralement n'importe où, voir les réponses ci-dessus.

0 votes

Je ne recommanderais pas d'injecter IConfiguration Ce que vous pouvez faire à la place est de créer des couches d'abstraction de ce dont vous avez besoin à partir de cette configuration et de les utiliser là où vous en avez besoin. De cette façon, votre code est plus sécurisé et ne dépend pas de IConfiguration ou de toute autre implémentation.

0 votes

Par moi ConfigurationBuilder ne pouvait pas être trouvé. J'utilise .NET Core 3.1.

55voto

Aseem Gautam Points 7269

Compléter la réponse de David Liang pour Core 2.0 -

appsettings.json sont liés à ASPNETCORE_ENVIRONMENT variable.

ASPNETCORE_ENVIRONMENT peut être défini à n'importe quelle valeur, mais trois valeurs sont prises en charge par le cadre : Development , Staging et Production . Si ASPNETCORE_ENVIRONMENT n'est pas définie, elle sera par défaut Production .

Pour ces trois valeurs, ces appsettings.ASPNETCORE_ENVIRONMENT.json sont pris en charge dès le départ - appsettings.Staging.json , appsettings.Development.json et appsettings.Production.json

Les trois fichiers json de paramètres d'application ci-dessus peuvent être utilisés pour configurer plusieurs environnements.

Exemple - appsettings.Staging.json

{
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "System": "Information",
            "Microsoft": "Information"
        }
    },
    "MyConfig": "My Config Value for staging."
}

Utilisez Configuration["config_var"] pour récupérer toute valeur de configuration.

public class Startup
{
    public Startup(IHostingEnvironment env, IConfiguration config)
    {
        Environment = env;
        Configuration = config;
        var myconfig = Configuration["MyConfig"];
    }

    public IConfiguration Configuration { get; }
    public IHostingEnvironment Environment { get; }
}

1 votes

Qu'en est-il des objets imbriqués ?

9 votes

Les objets imbriqués peuvent être obtenus avec Configuration["MyConfig:SomethingNested"]

1 votes

Comme on peut le voir dans le fichier github.com/aspnet/AspNetCore/blob/master/src/DefaultBuilder/src/ à la ligne 167 ASP.NET Core charge actuellement appsettings.json + appsettings.{env.EnvironmentName}.json . Ainsi, l'affirmation selon laquelle ASP.NET Core ne charge que les fichiers appsettings.json de développement, d'étape et de production est actuellement incorrecte.

39voto

harveyt Points 150

Je suppose que le moyen le plus simple est le DI. Un exemple d'atteinte au contrôleur.

// StartUp.cs
public void ConfigureServices(IServiceCollection services)
{
    ...
    // for get appsettings from anywhere
    services.AddSingleton(Configuration);
}

public class ContactUsController : Controller
{
    readonly IConfiguration _configuration;

    public ContactUsController(
        IConfiguration configuration)
    {
        _configuration = configuration;

        // sample:
        var apiKey = _configuration.GetValue<string>("SendGrid:CAAO");
        ...
    }
}

10 votes

En lisant les autres réponses, celle-ci devrait être la meilleure.

1 votes

Il me manquait services.AddSingleton(Configuration); Maintenant, cela fonctionne.

14voto

Shadi Namrouti Points 1453

Dans le constructeur de la classe Startup, vous pouvez accéder à appsettings.json et à de nombreux autres paramètres en utilisant l'objet IConfiguration injecté :

Startup.cs Constructeur

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;

        //here you go
        var myvalue = Configuration["Grandfather:Father:Child"];

    }

public IConfiguration Configuration { get; }

Contenu de appsettings.json

  {
  "Grandfather": {
    "Father": {
      "Child": "myvalue"
    }
  }

2 votes

C'est la syntaxe "Configuration["Grand-père:Père:Enfant"]" qui m'a aidé.

2 votes

Cette réponse est remarquable par sa structure, sa clarté et sa pertinence. Excellente communication

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X