Tirer parti de appsettings.json dans .net core

162

Je ne sais pas ce qui me manque ici, mais je ne parviens pas à obtenir les valeurs de mon appsettings.json dans mon application principale .net. J'ai mon appsettings.json comme:

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

Commencez:

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

Manette:

public class HomeController : Controller
{
    private readonly AppSettings _mySettings;

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

_mySettingsest toujours nul. Y a-t-il quelque chose qui me manque ici?

un homme
la source
3
Veuillez lire la documentation sur l'utilisation de la configuration. Vous avez mal configuré la configuration dans votre classe de démarrage.
poke
Merci pour la documentation. Cela a été utile.
aman
cela peut même être simplifié simplement en utilisant l'injection de dépendances d'IConfiguration. Ce qui est expliqué ici coding-issues.com/2018/10/…
Ranadheer Reddy

Réponses:

230

Programme et classe de démarrage

.NET Core 2.x

Vous n'avez pas besoin de nouveau IConfigurationdans le Startupconstructeur. Sa mise en œuvre 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 Startupde charger les fichiers de paramètres d'application.

// 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 configurez à partir des paramètres de l'application:

  • Utilisation simple ConfigurationBuilder.GetValue<T>
  • Utilisation du modèle d'options

Disons que votre appsettings.json apparence ressemble à ceci:

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

Manière simple

Vous pouvez injecter toute la configuration dans le constructeur de votre contrôleur / classe (via IConfiguration) et obtenir la valeur souhaitée 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);
    }
}

Modèle d'options

Cela 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 souhaitez pas coder en dur ces chaînes de clé à plusieurs endroits, il peut être plus facile d'utiliser le modèle d'options. . Le modèle d'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. Enregistrez l'instance de configuration à laquelle ces classes se lient
  3. Injectez IOptions<T>dans le constructeur du contrôleur / classe sur lequel vous voulez obtenir des valeurs

1. Définissez les classes de configuration pour représenter la structure

Vous pouvez définir des classes avec des propriétés qui doivent correspondre exactement aux 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 puis vous devez enregistrer cette instance de configuration 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 IOptions

Enfin, sur le contrôleur / la classe dont vous souhaitez obtenir les valeurs, vous devez injecter IOptions<AppIdentitySettings>via le 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);
    }
}
David Liang
la source
Comment puis-je accéder aux valeurs de la classe qui contient mes données?
Lukas Hieronimus Adler
1
@LukasHieronimusAdler: Vous voudrez peut-être utiliser à la IOptionsSnapshot<T>place de IOptions<T>. Vous pouvez consulter cet article: offer.solutions/blog/articles/2017/02/17/… . Je n'ai cependant pas eu l'occasion de l'essayer moi-même.
David Liang
2
Pourriez-vous faire simple comme un extrait de code?
Syaiful Nizam Yahya
8
Quel horrible pas en arrière à partir de la pile complète .net
Aaron
4
Ok, donc pour .NET Core 3, vous avez besoin du package Microsoft.Extensions.Options.ConfigurationExtensions et cela fonctionne bien
Tomas Bruckner
50

Créez simplement un fichier AnyName.cs et collez 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();
        }
    }
}

Doit remplacer le nom de fichier YouAppSettingFile.json par votre nom de fichier.
Votre fichier .json devrait ressembler à ci-dessous.

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

Vous pouvez maintenant l'utiliser.
N'oubliez pas d' ajouter une référence dans votre classe là où vous souhaitez 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"];
shajji
la source
3
Ne l'utilisez pas en production. C'est cette approche qui a causé des fuites de mémoire dans notre API Web. Si vous utilisez netcore, vous pouvez injecter IConfiguration littéralement n'importe où, voyez simplement les réponses ci-dessus.
André Mantas
49

Ajout à la réponse de David Liang pour Core 2.0 -

appsettings.jsonles fichiers sont liés à la ASPNETCORE_ENVIRONMENTvariable.

ASPNETCORE_ENVIRONMENTpeut être réglé à une valeur, mais trois valeurs sont prises en charge par le cadre: Development, Staginget Production. S'il ASPNETCORE_ENVIRONMENTn'est pas défini, il sera par défaut Production.

Pour ces trois valeurs, ces fichiers appsettings.ASPNETCORE_ENVIRONMENT.json sont pris en charge par défaut - appsettings.Staging.json, appsettings.Development.jsonetappsettings.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; }
}
Aseem Gautam
la source
1
Qu'en est-il des objets imbriqués?
Arthur Attout
8
Les objets imbriqués peuvent être obtenus avec Configuration ["MyConfig: SomethingNested"]
WeHaveCookies
1
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, de préparation et de production est actuellement incorrecte.
mvdgun
1
alors suis-je censé définir la variable Windows à ASPNETCORE_ENVIRONMENTchaque fois? Les choses étaient beaucoup plus faciles dans .Net 4. Ces fanatiques de JSON ont tout gâché
Boîte à outils
@Toolkit Vous pouvez définir la variable d'environnement globalement. docs.microsoft.com/en-us/aspnet/core/fundamentals/…
Aseem Gautam
29

Je suppose que le moyen le plus simple est par DI. Un exemple d'accès 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");
        ...
    }
}
Harveyt
la source
5
En lisant les autres réponses, cela devrait être la meilleure.
harveyt
Je manquais services.AddSingleton(Configuration);, maintenant ça marche
Arthur Medeiros
12

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

Constructeur Startup.cs

    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"
    }
  }
Shadi Namrouti
la source
2
C'est la syntaxe "Configuration [" Grandfather: Father: Child "]" qui m'a aidé.
Jacques Olivier
2
C'est une réponse remarquable dans la manière dont elle est structurée, claire et précise. Great communication
jolySoft
6
    public static void GetSection()
    {
        Configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .Build();

        string BConfig = Configuration.GetSection("ConnectionStrings")["BConnection"];

    }
Sepideh Dalirpour
la source
4
Réponse incomplète
Carlos ABS
1

Dans mon cas, c'était simple comme utiliser la méthode Bind () sur l'objet Configuration. Et puis ajoutez l'objet en tant que singleton dans la DI.

var instructionSettings = new InstructionSettings();
Configuration.Bind("InstructionSettings", instructionSettings);
services.AddSingleton(typeof(IInstructionSettings), (serviceProvider) => instructionSettings);

L'objet Instruction peut être aussi complexe que vous le souhaitez.

{  
 "InstructionSettings": {
    "Header": "uat_TEST",
    "SVSCode": "FICA",
    "CallBackUrl": "https://UATEnviro.companyName.co.za/suite/webapi/receiveCallback",
    "Username": "s_integrat",
    "Password": "X@nkmail6",
    "Defaults": {
    "Language": "ENG",
    "ContactDetails":{
       "StreetNumber": "9",
       "StreetName": "Nano Drive",
       "City": "Johannesburg",
       "Suburb": "Sandton",
       "Province": "Gauteng",
       "PostCode": "2196",
       "Email": "[email protected]",
       "CellNumber": "0833 468 378",
       "HomeNumber": "0833 468 378",
      }
      "CountryOfBirth": "710"
    }
  }
Lizo Matala
la source
1

Pour ASP.NET Core 3.1, vous pouvez suivre ce guide:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

Lorsque vous créez un nouveau projet ASP.NET Core 3.1, vous aurez la ligne de configuration suivante dans Program.cs:

Host.CreateDefaultBuilder(args)

Cela permet ce qui suit:

  1. ChainedConfigurationProvider: ajoute une IConfiguration existante en tant que source. Dans le cas de la configuration par défaut, ajoute la configuration d'hôte et la définit comme première source pour la configuration de l'application.
  2. appsettings.json à l'aide du fournisseur de configuration JSON.
  3. appsettings.Environment.json à l'aide du fournisseur de configuration JSON. Par exemple, appsettings.Production.json et appsettings.Development.json.
  4. Secrets d'application lorsque l'application s'exécute dans l'environnement de développement.
  5. Variables d'environnement à l'aide du fournisseur de configuration des variables d'environnement.
  6. Arguments de ligne de commande à l'aide du fournisseur de configuration de ligne de commande.

Cela signifie que vous pouvez injecter IConfigurationet récupérer des valeurs avec une clé de chaîne, même des valeurs imbriquées. CommeIConfiguration["Parent:Child"];

Exemple:

appsettings.json

{
  "ApplicationInsights":
    {
        "Instrumentationkey":"putrealikeyhere"
    }
}

WeatherForecast.cs

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;
    private readonly IConfiguration _configuration;

    public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        var key = _configuration["ApplicationInsights:InstrumentationKey"];

        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}
Ogglas
la source
Où puis-je en savoir plus sur la IConfiguration["Parent:Child"]syntaxe?
xr280xr le
0

Je pense que la meilleure option est:

  1. Créer une classe de modèle en tant que schéma de configuration

  2. Inscrivez-vous dans DI: services.Configure (Configuration.GetSection ("democonfig"));

  3. Obtenez les valeurs en tant qu'objet modèle à partir de DI dans votre contrôleur:

    private readonly your_model myConfig;
    public DemoController(IOptions<your_model> configOps)
    {
        this.myConfig = configOps.Value;
    }
Meghnath Das
la source
0

Depuis Asp.net core 2.2 vers ci-dessus, vous pouvez coder comme ci-dessous:

Étape 1. Créez un fichier de classe AppSettings.

Ce fichier contient des méthodes permettant d'obtenir une valeur par clé à partir du fichier appsettings.json. Ressemble au code ci-dessous:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ReadConfig.Bsl
{
  public class AppSettings
  {
      private static AppSettings _instance;
      private static readonly object ObjLocked = new object();
      private IConfiguration _configuration;

      protected AppSettings()
      {
      }

      public void SetConfiguration(IConfiguration configuration)
      {
          _configuration = configuration;
      }

      public static AppSettings Instance
      {
          get
          {
              if (null == _instance)
              {
                  lock (ObjLocked)
                  {
                      if (null == _instance)
                          _instance = new AppSettings();
                  }
              }
              return _instance;
          }
      }

      public string GetConnection(string key, string defaultValue = "")
      {
          try
          {
              return _configuration.GetConnectionString(key);
          }
          catch
          {
              return defaultValue;
          }
      }

      public T Get<T>(string key = null)
      {
          if (string.IsNullOrWhiteSpace(key))
              return _configuration.Get<T>();
          else
              return _configuration.GetSection(key).Get<T>();
      }

      public T Get<T>(string key, T defaultValue)
      {
          if (_configuration.GetSection(key) == null)
              return defaultValue;

          if (string.IsNullOrWhiteSpace(key))
              return _configuration.Get<T>();
          else
              return _configuration.GetSection(key).Get<T>();
      }

      public static T GetObject<T>(string key = null)
      {
          if (string.IsNullOrWhiteSpace(key))
              return Instance._configuration.Get<T>();
          else
          {
              var section = Instance._configuration.GetSection(key);
              return section.Get<T>();
          }
      }

      public static T GetObject<T>(string key, T defaultValue)
      {
          if (Instance._configuration.GetSection(key) == null)
              return defaultValue;

          if (string.IsNullOrWhiteSpace(key))
              return Instance._configuration.Get<T>();
          else
              return Instance._configuration.GetSection(key).Get<T>();
      }
  }
}

Étape 2. Configuration initiale de l'objet AppSettings

Nous devons déclarer et charger le fichier appsettings.json au démarrage de l'application et charger les informations de configuration pour l'objet AppSettings. Nous allons faire ce travail dans le constructeur du fichier Startup.cs. Veuillez noter la ligneAppSettings.Instance.SetConfiguration(Configuration);

public Startup(IHostingEnvironment evm)
{
    var builder = new ConfigurationBuilder()
      .SetBasePath(evm.ContentRootPath)
      .AddJsonFile("appsettings.json", true, true)
      .AddJsonFile($"appsettings.{evm.EnvironmentName}.json", true)
      .AddEnvironmentVariables();
    Configuration = builder.Build(); // load all file config to Configuration property 
    AppSettings.Instance.SetConfiguration(Configuration);       
}

OK, maintenant j'ai un fichier appsettings.json avec quelques clés comme ci-dessous:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "ConnectionString": "Data Source=localhost;Initial Catalog=ReadConfig;Persist Security Info=True;User ID=sa;Password=12345;"
  },
  "MailConfig": {
    "Servers": {
      "MailGun": {
        "Pass": "65-1B-C9-B9-27-00",
        "Port": "587",
        "Host": "smtp.gmail.com"
      }
    },
    "Sender": {
      "Email": "[email protected]",
      "Pass": "123456"
    }
  }
}

Étape 3. Lire la valeur de configuration à partir d'une action

Je fais de la démo une action dans le contrôleur domestique comme ci-dessous:

public class HomeController : Controller
{
    public IActionResult Index()
    {
        var connectionString = AppSettings.Instance.GetConnection("ConnectionString");
        var emailSender = AppSettings.Instance.Get<string>("MailConfig:Sender:Email");
        var emailHost = AppSettings.Instance.Get<string>("MailConfig:Servers:MailGun:Host");

        string returnText = " 1. Connection String \n";
        returnText += "  " +connectionString;
        returnText += "\n 2. Email info";
        returnText += "\n Sender : " + emailSender;
        returnText += "\n Host : " + emailHost;

        return Content(returnText);
    }
}

Et ci-dessous est le résultat:

Cliquez pour voir le résultat

Pour plus d'informations, vous pouvez consulter l'article obtenir la valeur de appsettings.json dans asp.net core pour plus de détails sur le code.

Dung Do Tien
la source
0

C'est simple: dans appsettings.json

  "MyValues": {
    "Value1": "Xyz"
  }

Dans le fichier .cs:

static IConfiguration conf = (new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build());
        public static string myValue1= conf["MyValues:Value1"].ToString();
Abhishek Pandey
la source