web-dev-qa-db-fra.com

Comment lire les valeurs AppSettings à partir d'un fichier .json dans ASP.NET Core

J'ai configuré mes données AppSettings dans le fichier appsettings/config .json comme suit:

{
  "AppSettings": {
        "token": "1234"
    }
}

J'ai cherché en ligne sur la façon de lire les valeurs AppSettings à partir d'un fichier .json, mais je n'ai rien pu trouver d'utile.

J'ai essayé:

var configuration = new Configuration();
var appSettings = configuration.Get("AppSettings"); // null
var token = configuration.Get("token"); // null

Je sais avec ASP.NET 4.0 que vous pouvez faire ceci:

System.Configuration.ConfigurationManager.AppSettings["token"];

Mais comment puis-je faire cela dans ASP.NET Core?

179
Oluwafemi

Cela a eu quelques rebondissements. J'ai modifié cette réponse pour qu'elle soit à jour avec ASP.NET Core 2.0 (à la date du 26/02/2018).

Ceci provient principalement de la documentation officielle :

Pour utiliser les paramètres de votre application ASP.NET, il est recommandé d’instancier uniquement une classe Configuration dans la classe Startup de votre application. Ensuite, utilisez le modèle Options pour accéder aux paramètres individuels. Disons que nous avons un fichier appsettings.json qui ressemble à ceci:

{
  "MyConfig": {
   "ApplicationName": "MyApp",
   "Version": "1.0.0"
   }

}

Et nous avons un objet POCO représentant la configuration:

public class MyConfig
{
    public string ApplicationName { get; set; }
    public int Version { get; set; }
}

Maintenant, nous construisons la configuration dans Startup.cs:

public class Startup 
{
    public IConfigurationRoot Configuration { get; set; }

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

        Configuration = builder.Build();
    }
}

Notez que appsettings.json sera enregistré par défaut dans .NET Core 2.0. Nous pouvons également enregistrer un fichier de configuration appsettings.{Environment}.json par environnement si nécessaire.

Si nous voulons injecter notre configuration dans nos contrôleurs, nous devrons l'enregistrer auprès du moteur d'exécution. Nous le faisons via Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    // Add functionality to inject IOptions<T>
    services.AddOptions();

    // Add our Config object so it can be injected
    services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
}

Et on l'injecte comme ça:

public class HomeController : Controller
{
    private readonly IOptions<MyConfig> config;

    public HomeController(IOptions<MyConfig> config)
    {
        this.config = config;
    }

    // GET: /<controller>/
    public IActionResult Index() => View(config.Value);
}

La classe Startup complète:

public class Startup 
{
    public IConfigurationRoot Configuration { get; set; }

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

        Configuration = builder.Build();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        // Add functionality to inject IOptions<T>
        services.AddOptions();

        // Add our Config object so it can be injected
        services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
    }
}
246
Yuval Itzchakov

Tout d'abord: le nom d'assembly et l'espace de noms de Microsoft.Framework.ConfigurationModel ont été remplacés par Microsoft.Framework.Configuration. Donc, vous devriez utiliser: par exemple.

"Microsoft.Framework.Configuration.Json": "1.0.0-beta7"

en tant que dépendance dans project.json. Utilisez beta5 ou 6 si vous n'avez pas installé 7. Ensuite, vous pouvez faire quelque chose comme ceci dans Startup.cs.

public IConfiguration Configuration { get; set; }

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
     var configurationBuilder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
        .AddJsonFile("config.json")
        .AddEnvironmentVariables();
     Configuration = configurationBuilder.Build();
}

Si vous voulez ensuite récupérer une variable du fichier config.json, vous pouvez l'obtenir immédiatement en utilisant:

public void Configure(IApplicationBuilder app)
    {
        // Add .Value to get the token string
        var token = Configuration.GetSection("AppSettings:token");
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("This is a token with key (" + token.Key + ") " + token.Value);
        });
    }

ou vous pouvez créer une classe appelée AppSettings comme ceci:

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

et configurez les services comme ceci:

public void ConfigureServices(IServiceCollection services)
{       
    services.AddMvc();

    services.Configure<MvcOptions>(options =>
    {
        //mvc options
    });

    services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}

puis accédez-y, par exemple, à un contrôleur comme celui-ci:

public class HomeController : Controller
{
    private string _token;

    public HomeController(IOptions<AppSettings> settings)
    {
        _token = settings.Options.token;
    }
}
56
hug

Pour .NET Core 2.0, les choses ont un peu changé. Le constructeur de démarrage prend un objet de configuration en tant que paramètre. L'utilisation de ConfigurationBuilder n'est donc pas requise. Voici le mien:

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<StorageOptions>(Configuration.GetSection("AzureStorageConfig"));
}

Mon POCO est l'objet StorageOptions mentionné en haut:

namespace Brazzers.Models
{
    public class StorageOptions
    {
        public String StorageConnectionString { get; set; }
        public String AccountName { get; set; }
        public String AccountKey { get; set; }
        public String DefaultEndpointsProtocol { get; set; }
        public String EndpointSuffix { get; set; }

        public StorageOptions() { }
    }
}

Et la configuration est en fait une sous-section de mon fichier appsettings.json, nommé AzureStorageConfig:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;",
    "StorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=brazzerswebapp;AccountKey=Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==;EndpointSuffix=core.windows.net"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },

  "AzureStorageConfig": {
    "AccountName": "brazzerswebapp",
    "AccountKey": "Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==",
    "DefaultEndpointsProtocol": "https",
    "EndpointSuffix": "core.windows.net",
    "StorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=brazzerswebapp;AccountKey=Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==;EndpointSuffix=core.windows.net"
  }
}

La seule chose que j’ajouterai, c’est que, le constructeur ayant changé, je n’ai pas vérifié s’il fallait faire quelque chose de plus pour charger appsettings.<environmentname>.json plutôt que appsettings.json.

40
MDMoore313

Si vous voulez juste obtenir la valeur du jeton, utilisez

Configuration["AppSettings:token"]

19
kodebot

Suivre les travaux pour les applications console;

1- installer les packages nuget suivants (.csproj);

<ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0-preview2-35157" />
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0-preview2-35157" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0-preview2-35157" />
  </ItemGroup>

2- Créez appsettings.json au niveau racine. Faites un clic droit dessus et "Copier dans le répertoire de sortie" comme "Copier si plus récent".

3- Exemple de fichier de configuration:

{
  "AppConfig": {
    "FilePath": "C:\\temp\\logs\\output.txt"
  }
}

4- Program.cs

configurationSection.Key et configurationSection.Value auront des propriétés de configuration.

static void Main(string[] args)
{
    try
    {

        IConfigurationBuilder builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

        IConfigurationRoot configuration = builder.Build();
        // configurationSection.Key => FilePath
        // configurationSection.Value => C:\\temp\\logs\\output.txt
        IConfigurationSection configurationSection = configuration.GetSection("AppConfig").GetSection("FilePath");  

    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
}
10
Teoman shipahi

Avec Core 2.2, et de la manière la plus simple possible ...

public IActionResult Index([FromServices] IConfiguration config) 
{
    var myValue = config.GetValue<string>("MyKey");
}

appsettings.json est automatiquement chargé et disponible via l'injection de constructeur ou d'action. Il existe également une méthode GetSection sur IConfiguration. Pas besoin de modifier Startup.cs ou Program.cs si vous avez uniquement besoin de appsettings.json.

10
tnJed

Juste pour compléter la réponse de Yuval Itzchakov.

Vous pouvez charger la configuration sans fonction de générateur, vous pouvez simplement l'injecter.

public IConfiguration Configuration { get; set; }

public Startup(IConfiguration configuration)
{
   Configuration = configuration;
}
7
Tiago Barroso

Pour .NET Core 2.0, vous pouvez simplement:

Déclarez vos paires clé/valeur dans appsettings.json:

{
  "MyKey": "MyValue"
}

Injecter le service de configuration dans startup.cs et obtenir la valeur à l'aide du service

using Microsoft.Extensions.Configuration;

public class Startup
{
    public void Configure(IConfiguration configuration,
                          ... other injected services
                          )
    {
        app.Run(async (context) =>
        {
            string myValue = configuration["MyKey"];
            await context.Response.WriteAsync(myValue);
        });
7
Chris Halcrow

Je doute que ce soit une bonne pratique, mais cela fonctionne localement. Je mettrai à jour cette information si elle échoue lors de la publication/du déploiement (sur un service Web IIS).

Étape 1 - Ajoutez cette assemblée au sommet de votre classe (dans mon cas, la classe du contrôleur):

using Microsoft.Extensions.Configuration;

Étape 2 - Ajoutez ceci ou quelque chose comme ça:

var config = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json").Build();

Étape 3 - Appelez la valeur de votre clé en faisant ceci (retourne une chaîne):

config["NameOfYourKey"]
6

En plus des réponses existantes, je voudrais mentionner qu'il est parfois utile d'avoir méthodes d'extension pour IConfiguration par souci de simplicité.

Je conserve la configuration JWT dans appsettings.json afin que ma classe de méthodes d'extension ressemble à ceci:

public static class ConfigurationExtensions
{
    public static string GetIssuerSigningKey(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Authentication:JwtBearer:SecurityKey");
        return result;
    }

    public static string GetValidIssuer(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Authentication:JwtBearer:Issuer");
        return result;
    }

    public static string GetValidAudience(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Authentication:JwtBearer:Audience");
        return result;
    }

    public static string GetDefaultPolicy(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Policies:Default");
        return result;
    }

    public static SymmetricSecurityKey GetSymmetricSecurityKey(this IConfiguration configuration)
    {
        var issuerSigningKey = configuration.GetIssuerSigningKey();
        var data = Encoding.UTF8.GetBytes(issuerSigningKey);
        var result = new SymmetricSecurityKey(data);
        return result;
    }

    public static string[] GetCorsOrigins(this IConfiguration configuration)
    {
        string[] result =
            configuration.GetValue<string>("App:CorsOrigins")
            .Split(",", StringSplitOptions.RemoveEmptyEntries)
            .ToArray();

        return result;
    }
}

Cela vous évite beaucoup de lignes et vous écrivez juste un code propre et minimal:

...
x.TokenValidationParameters = new TokenValidationParameters()
{
    ValidateIssuerSigningKey = true,
    ValidateLifetime = true,
    IssuerSigningKey = _configuration.GetSymmetricSecurityKey(),
    ValidAudience = _configuration.GetValidAudience(),
    ValidIssuer = _configuration.GetValidIssuer()
};

Il est également possible d'enregistrer l'instance de IConfiguration en tant que singleton et de l'injecter où vous le souhaitez - j'utilise le conteneur Autofac, voici comment procéder:

var appConfiguration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
builder.Register(c => appConfiguration).As<IConfigurationRoot>().SingleInstance();

Vous pouvez faire la même chose avec MS Dependency Injection:

services.AddSingleton<IConfigurationRoot>(appConfiguration);
6
Alex Herman

Ils n'arrêtent pas de changer les choses - après avoir mis à jour VS et avoir la bombe du projet dans son ensemble, sur le chemin de la récupération et la nouvelle façon de procéder ressemble à ceci:

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

    if (env.IsDevelopment())
    {
        // For more details on using the user secret store see http://go.Microsoft.com/fwlink/?LinkID=532709
        builder.AddUserSecrets();
    }

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

J'ai continué à rater cette ligne!

.SetBasePath(env.ContentRootPath)
4
Monolithcode

Vous pouvez essayer ci-dessous le code. Cela fonctionne pour moi.

public class Settings
    {
        private static IHttpContextAccessor _HttpContextAccessor;
        public Settings(IHttpContextAccessor httpContextAccessor)
        {
            _HttpContextAccessor = httpContextAccessor;
        }
        public static void Configure(IHttpContextAccessor httpContextAccessor)
        {
            _HttpContextAccessor = httpContextAccessor;
        }
        public static IConfigurationBuilder Getbuilder()
        {
            var builder = new ConfigurationBuilder()
              .SetBasePath(Directory.GetCurrentDirectory())
              .AddJsonFile("appsettings.json");
            return builder;
        }

        public static string GetAppSetting(string key)
        {
            //return Convert.ToString(ConfigurationManager.AppSettings[key]);
            var builder = Getbuilder();
            var GetAppStringData = builder.Build().GetValue<string>("AppSettings:" + key);
            return GetAppStringData;
        }

        public static string GetConnectionString(string key="DefaultName")
        {
            var builder = Getbuilder();
            var ConnectionString = builder.Build().GetValue<string>("ConnectionStrings:"+key);
            return ConnectionString;
        }
    }

Ici, j'ai créé une classe pour obtenir une chaîne de connexion et les paramètres de l'application.

Je fichier Startup.cs vous devez inscrire classe comme ci-dessous.

public class Startup
{      

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {           

        var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
        Settings.Configure(httpContextAccessor);
    }
}
2
jishan siddique

Voici le cas d'utilisation complet pour ASP.NET Core!

articles.json

{
  "shownArticlesCount": 3,
  "articles": [
    {
      "title": "My Title 1",
      "thumbnailLink": "example.com/img1.png",
      "authorProfileLink": "example.com/@@alper",
      "authorName": "Alper Ebicoglu",
      "publishDate": "2018-04-17",
      "text": "...",
      "link": "..."
    },
    {
      "title": "My Title 2",
      "thumbnailLink": "example.com/img2.png",
      "authorProfileLink": "example.com/@@alper",
      "authorName": "Alper Ebicoglu",
      "publishDate": "2018-04-17",
      "text": "...",
      "link": "..."
    },
  ]
}

ArticleContainer.cs

public class ArticleContainer
{
    public int ShownArticlesCount { get; set; }

    public List<Article> Articles { get; set; }
}

public class Article
{
    public string Title { get; set; }

    public string ThumbnailLink { get; set; }

    public string AuthorName { get; set; }

    public string AuthorProfileLink { get; set; }

    public DateTime PublishDate { get; set; }

    public string Text { get; set; }

    public string Link { get; set; } 
}

Startup.cs

public class Startup
{
    public IConfigurationRoot ArticleConfiguration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        ArticleConfiguration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("articles.json")
            .Build();
    }

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddOptions();

        services.Configure<ArticleContainer>(ArticleConfiguration);
    }
}

Index.cshtml.cs

public class IndexModel : PageModel
{
    public ArticleContainer ArticleContainer { get;set; }

    private readonly IOptions<ArticleContainer> _articleContainer;

    public IndexModel(IOptions<ArticleContainer> articleContainer)
    {
        _articleContainer = articleContainer;
    }

    public void OnGet()
    {
        ArticleContainer = _articleContainer.Value;
    }
}

Index.cshtml.cs

<h1>@Model.ArticleContainer.ShownArticlesCount</h1>
2
Alper Ebicoglu

Était-ce "tricher"? Je viens de rendre ma configuration statique dans la classe Startup, puis je peux y accéder de n'importe où:

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.Microsoft.com/fwlink/?LinkID=398940
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }

    public static IConfiguration Configuration { get; set; }
1
Brian Moore

Obtenez-le à l'intérieur du contrôleur en tant qu'objet via l'appel Get<YourType>()

public IActionResult Index([FromServices] IConfiguration config) { BillModel model= config.GetSection("Yst.Requisites").Get<BillModel>(); return View(model); }

0
Lapenkov Vladimir