1. ホーム
  2. c#

[解決済み】.net coreでappsettings.jsonから値を取得する。

2022-04-16 23:53:57

質問

何が足りないのかわかりませんが、.net coreアプリケーションの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です。何か見落としがあるのでしょうか?

解決方法は?

プログラム・スタートアップクラス

.NET Core 2.x

を新たに作成する必要はありません。 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;
    }
}

.NET Core 1.x

を伝える必要があります。 Startup を使用して、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();
    }
    ...
}



値の取得

アプリの設定から設定した値を取得するには、様々な方法があります。

例えば、あなたの appsettings.json はこのようになります。

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

シンプルな方法

コントローラ/クラスのコンストラクタに設定全体をインジェクトすることができます ( IConfiguration を指定し、指定したキーで必要な値を取得します。

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

オプションパターン

ConfigurationBuilder.GetValue<T> は、アプリの設定から1つか2つの値しか必要としない場合、非常に有効です。しかし、アプリの設定から複数の値を取得したい場合や、複数の場所でキー文字列をハードコードしたくない場合は、次のように使用する方が簡単です。 オプションパターン . オプションパターンは、階層/構造を表すためにクラスを使用します。

オプションパターンを使用するには

  1. 構造を表現するためのクラスを定義する
  2. これらのクラスがバインドするコンフィギュレーション・インスタンスを登録する
  3. インジェクト IOptions<T> を、値を取得したいコントローラ/クラスのコンストラクタに追加します。

1. 構造を表現するための構成クラスを定義する

というプロパティを持つクラスを定義することができます。 と完全に一致する必要があります。 は、アプリの設定にあるキーです。クラスの名前は、アプリの設定にあるセクションの名前と一致する必要はありません。

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. 設定インスタンスの登録

そして、このコンフィギュレーションインスタンスを ConfigureServices() を起動時に実行します。

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. IOオプションの注入

最後に、値を取得したいコントローラ/クラス上で IOptions<AppIdentitySettings> をコンストラクタで実行します。

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