Wertschöpfung aus appsettings.json im .net-Kern

160

Ich bin mir nicht sicher, was ich hier vermisse, aber ich kann die Werte aus meiner appsettings.json in meiner .net-Kernanwendung nicht abrufen. Ich habe meine appsettings.json als:

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

Anfang:

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

Modell:

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

Regler:

public class HomeController : Controller
{
    private readonly AppSettings _mySettings;

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

_mySettingsist immer null. Fehlt mir hier etwas?

ein Mann
quelle
3
Bitte lesen Sie die Dokumentation zur Verwendung der Konfiguration. Sie haben die Konfiguration in Ihrer Startklasse nicht ordnungsgemäß eingerichtet.
Poke
Danke für die Dokumentation. Das war hilfreich.
Aman
Dies kann sogar vereinfacht werden, indem nur die Abhängigkeitsinjektion von IConfiguration verwendet wird. Was hier erklärt wird Kodierung-issues.com/2018/10/…
Ranadheer Reddy

Antworten:

226

Programm- und Startklasse

.NET Core 2.x.

Sie müssen IConfigurationim StartupKonstruktor nicht neu sein. Seine Implementierung wird vom DI-System injiziert.

// 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.

Sie müssen Startupangeben , dass die Appsettings-Dateien geladen werden sollen.

// 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();
    }
    ...
}

Werte bekommen

Es gibt viele Möglichkeiten, den von Ihnen konfigurierten Wert aus den App-Einstellungen abzurufen:

  • Einfache Verwendung ConfigurationBuilder.GetValue<T>
  • Verwenden des Optionsmusters

Nehmen wir an, Sie sehen so appsettings.jsonaus:

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

Einfacher Weg

Sie können die gesamte Konfiguration (via IConfiguration) in den Konstruktor Ihres Controllers / Ihrer Klasse einfügen und mit einem angegebenen Schlüssel den gewünschten Wert erhalten:

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

Optionsmuster

Das ConfigurationBuilder.GetValue<T>funktioniert hervorragend, wenn Sie nur einen oder zwei Werte aus den App-Einstellungen benötigen. Wenn Sie jedoch mehrere Werte aus den App-Einstellungen abrufen oder diese Schlüsselzeichenfolgen nicht an mehreren Stellen fest codieren möchten, ist es möglicherweise einfacher, das Optionsmuster zu verwenden . Das Optionsmuster verwendet Klassen, um die Hierarchie / Struktur darzustellen.

So verwenden Sie das Optionsmuster:

  1. Definieren Sie Klassen, um die Struktur darzustellen
  2. Registrieren Sie die Konfigurationsinstanz, an die diese Klassen binden
  3. Injizieren Sie IOptions<T>in den Konstruktor des Controllers / der Klasse, für die Sie Werte erhalten möchten

1. Definieren Sie Konfigurationsklassen, um die Struktur darzustellen

Sie können Klassen mit Eigenschaften definieren, die genau mit den Schlüsseln in Ihren App-Einstellungen übereinstimmen müssen . Der Name der Klasse muss nicht mit dem Namen des Abschnitts in den App-Einstellungen übereinstimmen:

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. Registrieren Sie die Konfigurationsinstanz

Und dann müssen Sie diese Konfigurationsinstanz ConfigureServices()beim Start registrieren :

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. Injizieren Sie IOptions

Zuletzt müssen Sie auf dem Controller / der Klasse, auf der Sie die Werte erhalten möchten, über den IOptions<AppIdentitySettings>Konstruktor injizieren :

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
quelle
Wie kann ich auf die Werte in der Klasse zugreifen, die meine Daten enthält?
Lukas Hieronimus Adler
1
@LukasHieronimusAdler: Vielleicht möchten Sie IOptionsSnapshot<T>stattdessen verwenden IOptions<T>. Sie können sich diesen Artikel ansehen: issue.solutions/blog/articles/2017/02/17/… . Ich hatte jedoch keine Gelegenheit, es selbst zu versuchen.
David Liang
2
Könnten Sie es einfach machen wie ein Ausschnitt?
Syaiful Nizam Yahya
8
Was für ein schrecklicher Rückschritt von Full Stack .net
Aaron
4
Ok, für .NET Core 3 benötigen Sie das Paket Microsoft.Extensions.Options.ConfigurationExtensions und es funktioniert einwandfrei
Tomas Bruckner
50

Erstellen Sie einfach eine AnyName.cs-Datei und fügen Sie den folgenden Code ein.

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

Der Dateiname YouAppSettingFile.json muss durch Ihren Dateinamen ersetzt werden.
Ihre .json-Datei sollte wie folgt aussehen.

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

Jetzt können Sie es verwenden.
Vergessen Sie nicht, Referenz in Ihrer Klasse hinzuzufügen, in der Sie verwenden möchten.

using Custom;

Code zum Abrufen des Werts.

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
quelle
3
Verwenden Sie dies nicht in der Produktion. Dieser Ansatz verursachte Speicherlecks in unserer Web-API. Wenn Sie Netcore verwenden, können Sie IConfiguration buchstäblich überall einfügen. Lesen Sie einfach die obigen Antworten.
André Mantas
49

Hinzufügen zu David Liangs Antwort für Core 2.0 -

appsettings.jsonDateien sind mit ASPNETCORE_ENVIRONMENTVariablen verknüpft .

ASPNETCORE_ENVIRONMENTkann auf einen beliebigen Wert eingestellt werden, aber drei Werte werden vom Framework unterstützt: Development, Staging, und Production. Wenn ASPNETCORE_ENVIRONMENTnicht festgelegt, wird standardmäßig auf Production.

Für diese drei Werte werden die Dateien appsettings.ASPNETCORE_ENVIRONMENT.json sofort unterstützt - appsettings.Staging.json,appsettings.Development.json undappsettings.Production.json

Die oben genannten drei JSON-Dateien mit Anwendungseinstellungen können zum Konfigurieren mehrerer Umgebungen verwendet werden.

Beispiel - appsettings.Staging.json

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

Verwenden Sie Configuration["config_var"]diese Option , um einen beliebigen Konfigurationswert abzurufen.

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
quelle
1
Was ist mit verschachtelten Objekten?
Arthur Attout
8
Verschachtelte Objekte können mit Konfiguration ["MyConfig: SomethingNested"]
WeHaveCookies
1
Wie in der Datei github.com/aspnet/AspNetCore/blob/master/src/DefaultBuilder/src/… in Zeile 167 zu sehen ist, lädt ASP.NET Core derzeit appsettings.json+ appsettings.{env.EnvironmentName}.json. Daher ist die Aussage, dass ASP.NET Core nur die Entwicklungs-, Staging- und Produktionsdateien appsettings.json lädt, derzeit falsch.
MVDgun
1
Soll ich also ASPNETCORE_ENVIRONMENTjedes Mal die Windows-Variable festlegen ? In .Net 4 war es viel einfacher. Diese JSON-Fanatiker haben es sehr vermasselt
Toolkit
@Toolkit Sie können die Umgebungsvariable global festlegen. docs.microsoft.com/en-us/aspnet/core/fundamentals/…
Aseem Gautam
29

Ich denke, der einfachste Weg ist von DI. Ein Beispiel für das Erreichen von Controller.

// 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
quelle
5
Wenn Sie die anderen Antworten lesen, sollte dies das Beste sein.
Harvey
Ich wurde vermisst services.AddSingleton(Configuration);, jetzt funktioniert es
Arthur Medeiros
12

Im Konstruktor der Startup-Klasse können Sie mit dem injizierten IConfiguration-Objekt auf appsettings.json und viele andere Einstellungen zugreifen:

Startup.cs Konstruktor

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;

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

    }

public IConfiguration Configuration { get; }

Inhalt von appsettings.json

  {
  "Grandfather": {
    "Father": {
      "Child": "myvalue"
    }
  }
Shadi Namrouti
quelle
2
Es war die Syntax 'Konfiguration ["Großvater: Vater: Kind"]', die mir geholfen hat.
Jacques Olivier
2
Dies ist eine hervorragende Antwort in der Art und Weise, wie sie strukturiert, klar und auf den Punkt gebracht ist. Tolle Kommunikation
jolySoft
6
    public static void GetSection()
    {
        Configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .Build();

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

    }
Sepideh Dalirpour
quelle
4
Unvollständige Antwort
Carlos ABS
1

In meinem Fall war es einfach, die Bind () -Methode für das Konfigurationsobjekt zu verwenden. Fügen Sie dann das Objekt als Singleton in den DI ein.

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

Das Anweisungsobjekt kann so komplex sein, wie Sie möchten.

{  
 "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
quelle
1

Für ASP.NET Core 3.1 können Sie dieser Anleitung folgen:

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

Wenn Sie ein neues ASP.NET Core 3.1-Projekt erstellen, wird die folgende Konfigurationszeile angezeigt Program.cs:

Host.CreateDefaultBuilder(args)

Dies ermöglicht Folgendes:

  1. ChainedConfigurationProvider: Fügt eine vorhandene IConfiguration als Quelle hinzu. Fügt im Standardkonfigurationsfall die Hostkonfiguration hinzu und legt sie als erste Quelle für die App-Konfiguration fest.
  2. appsettings.json mit dem JSON-Konfigurationsanbieter.
  3. appsettings.Environment.json mit dem JSON-Konfigurationsanbieter. Zum Beispiel appsettings.Production.json und appsettings.Development.json.
  4. App-Geheimnisse, wenn die App in der Entwicklungsumgebung ausgeführt wird.
  5. Umgebungsvariablen mit dem Konfigurationsanbieter für Umgebungsvariablen.
  6. Befehlszeilenargumente mit dem Befehlszeilenkonfigurationsanbieter.

Dies bedeutet, dass Sie IConfigurationWerte mit einem Zeichenfolgenschlüssel einfügen und abrufen können, auch verschachtelte Werte. MögenIConfiguration["Parent:Child"];

Beispiel:

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
quelle
Wo kann ich mehr über die IConfiguration["Parent:Child"]Syntax erfahren ?
xr280xr
0

Ich denke, die beste Option ist:

  1. Erstellen Sie eine Modellklasse als Konfigurationsschema

  2. Registrieren Sie sich in DI: services.Configure (Configuration.GetSection ("democonfig"));

  3. Rufen Sie die Werte als Modellobjekt von DI in Ihrem Controller ab:

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

Von Asp.net Core 2.2 bis oben können Sie wie folgt codieren:

Schritt 1. Erstellen Sie eine AppSettings-Klassendatei.

Diese Datei enthält einige Methoden, mit denen Sie den Wert anhand des Schlüssels aus der Datei appsettings.json ermitteln können. Sehen Sie wie folgt aus:

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

Schritt 2. Erstkonfiguration für das AppSettings-Objekt

Wir müssen die Datei appsettings.json deklarieren und laden, wenn die Anwendung gestartet wird, und Konfigurationsinformationen für das AppSettings-Objekt laden. Wir werden diese Arbeit im Konstruktor der Datei Startup.cs ausführen. Bitte beachten Sie die ZeileAppSettings.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);       
}

Okay, jetzt habe ich eine appsettings.json-Datei mit einigen Schlüsseln wie folgt:

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

Schritt 3. Lesen Sie den Konfigurationswert aus einer Aktion

Ich mache Demo eine Aktion in Home Controller wie folgt:

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

Und unten ist das Ergebnis:

Klicken Sie hier, um das Ergebnis anzuzeigen

Weitere Informationen finden Sie im Artikel get value from appsettings.json im asp.net-Kern, um detaillierteren Code zu erhalten.

Dung Do Tien
quelle