web-dev-qa-db-ja.com

.netコアのappsettings.jsonから価値を得る

何が足りないのかわからないが、私の.netコアアプリケーションのappsettings.jsonから値を取得できない私は私のappsettings.jsonを持っています:

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

起動:

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

モデル:

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

コントローラ:

public class HomeController : Controller
{
    private readonly AppSettings _mySettings;

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

_mySettingsは常にnullです。ここに足りないものはありますか。

80
aman

コア2.0

IConfigurationコンストラクタに新しいStartupを追加する必要はありません。その実装は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;
    }
}

ボーナス:

クラスライブラリを使用してソリューションを複数のプロジェクトに分割する場合は、 Microsoft.Extensions.Options.ConfigurationExtensions パッケージを使用してappsettingsファイルから値を読み取り、それらをプロジェクト内の構成クラスに注入することができます。

それはあなたが使うことができる2つの拡張子を持っています:

public static T Get<T>(this IConfiguration configuration);
public static IServiceCollection Configure<TOptions>(this IServiceCollection services, 
    IConfiguration config) where TOptions : class;

例:

私はMicrosoft.AspNetCore.Identityを使っているすべてのセキュリティ関連サービスをDL.SO.Services.Securityと呼ばれるそれ自身のプロジェクトに入れました。

appsettings.jsonのセキュリティ設定

私のWeb /スタートアッププロジェクトのASP.NET Core Identityフレームワークで設定したいアイデンティティオプションのために "AppIdentitySettings"と呼ばれる設定を定義します。

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

設定クラス

それからappsettings.jsonであなたの設定構造を表現するためにあなたはただPOCOである設定クラスを定義する必要があります。設定クラスの名前はappsettings.jsonで定義したセクション名と一致する必要はありませんが、プロパティの名前は一致する必要があります。

namespace DL.SO.Services.Security
{
    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; }
    }
}

拡張方法

あなたのWebプロジェクトのStartupappsettings.jsonとそれらの設定クラス間のバインディングを設定することができます。しかし、プラグアンドプレイができるように、私は別のプロジェクトで拡張メソッドを定義することを好みます。

using DL.SO.Services.Security.Entities;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace DL.SO.Services.Security.Extensions
{
    public static class ServiceCollectionExtensions
    {
        public static void AddIdentitySecurityService(this IServiceCollection services, 
            IConfiguration configuration)
        {
            string connectionString = configuration.GetConnectionString("AppDbConnection");
            string assemblyNamespace = typeof(AppIdentityDbContext).Namespace;

            var settingsSection = configuration.GetSection("AppIdentitySettings");
            var settings = settingsSection.Get<AppIdentitySettings>();

            // Inject AppIdentitySettings so that others can use too
            services.Configure<AppIdentitySettings>(settingsSection);

            services.AddDbContext<AppIdentityDbContext>(options =>
                options.UseSqlServer(connectionString, optionsBuilder =>
                    optionsBuilder.MigrationsAssembly(assemblyNamespace)
                )
            );

            services.AddIdentity<AppUser, AppRole>(options =>
            {
                // User settings
                options.User.RequireUniqueEmail = settings.User.RequireUniqueEmail;

                // Password settings
                options.Password.RequireDigit = settings.Password.RequireDigit;
                options.Password.RequiredLength = settings.Password.RequiredLength;
                options.Password.RequireLowercase = settings.Password.RequireLowercase;
                options.Password.RequireNonAlphanumeric = settings.Password.RequireNonAlphanumeric;
                options.Password.RequireUppercase = settings.Password.RequireUppercase;

                // Lockout settings
                options.Lockout.AllowedForNewUsers = settings.Lockout.AllowedForNewUsers;
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(settings.Lockout.DefaultLockoutTimeSpanInMins);
                options.Lockout.MaxFailedAccessAttempts = settings.Lockout.MaxFailedAccessAttempts;
            })
            .AddEntityFrameworkStores<AppIdentityDbContext>()
            .AddDefaultTokenProviders();
        }
    }
}

メインスタートアップに接続します

namespace DL.SO.Web.UI
{
    ...

    public void ConfigureServices(IServiceCollection services)
    {
        // Configure ASP.NET Core Identity
        services.AddIdentitySecurityService(this.Configuration);

        ...
    }
}

コア1.x

AppsettingsファイルをロードするようにStartupに指示する必要があります。

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

指摘してくれてありがとう@Kirk!

96
David Liang

Core 2.0 - に対するDavid Liangの回答に追加

appsettings.jsonファイルはASPNETCORE_ENVIRONMENT変数にリンクされています。

ASPNETCORE_ENVIRONMENTは任意の値に設定できますが、フレームワークではDevelopmentStaging、およびProductionの3つの値がサポートされています。 ASPNETCORE_ENVIRONMENTが設定されていない場合、デフォルトはProductionになります。

これらの3つの値に対して、これらの appsettings.ASPNETCORE_ENVIRONMENT.json ファイルはそのまま使用できます - appsettings.Staging.jsonappsettings.Development.jsonおよびappsettings.Production.json

上記の3つのアプリケーション設定JSONファイルを使用して、複数の環境を構成できます。

例 - appsettings.Staging.json

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

設定値を取得するにはConfiguration["config_var"]を使用します。

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; }
}
34
Aseem Gautam

An AnyName.csファイルを作成して、次のコードを貼り付けるだけです。

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

YouAppSettingFile.jsonファイル名を自分のファイル名に置き換える必要があります。
あなたの.jsonファイルは以下のようになるはずです。

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

今、あなたはそれを使うことができます。
使用したいクラスに 参照を追加 を忘れないでください。

using Custom;

値を取得するためのコード.

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

最も簡単な方法はDIによるものだと思います。コントローラーに手を伸ばす例。

// 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");
        ...
    }
}
18
harveyt

Startupクラスのコンストラクタでは、注入されたIConfigurationオブジェクトを使用してappsettings.jsonやその他多くの設定にアクセスできます。

Startup.csコンストラクタ

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;

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

    }

public IConfiguration Configuration { get; }

appsettings.json の内容

  {
  "Grandfather": {
    "Father": {
      "Child": "myvalue"
    }
  }
5
Shadi Namrouti
    public static void GetSection()
    {
        Configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .Build();

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

    }
2

私の場合は、ConfigurationオブジェクトのBind()メソッドを使用するのと同じくらい簡単でした。次に、オブジェクトをシングルトンとしてDIに追加します。

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

Instructionオブジェクトは、必要に応じて複雑にすることができます。

{  
 "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"
    }
  }
0
Lizo Matala