web-dev-qa-db-ja.com

ASP.NET Core 2.0でappSettings.jsonのカスタムキーが機能しない

ASP.NET CoreプロジェクトのappSettings.jsonにCustomSettingsセクションキーを追加しました。

{
  "ConnectionStrings": {
    "DefaultConnectionString": "Data Source=..."
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "CustomSettings": {
    "Culture": "es-CO"
  }
}

次のコントローラーでカルチャーキーを読み込めませんでした。

public AccountController(
            UserManager<ApplicationUser> userManager,
            SignInManager<ApplicationUser> signInManager,
            IEmailSender emailSender,
            ILogger<AccountController> logger,
            IConfiguration configuration)
{
   Response.Cookies.Append(
                    CookieRequestCultureProvider.DefaultCookieName,
                    CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(configuration.GetSection("CustomSettings")["Culture"])),
                    new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
            );
}

以下を実行しても、常にNULLが返されます。configuration.GetSection( "CustomSettings")["Culture"]; configuration.GetSection( "CustomSettings")。GetValue( "Culture");

私は ASP.NET Core:Webプロジェクトとクラスライブラリのappsettings.jsonにアクセスするためのステップバイステップガイド に基づいてヘルプを試しましたが、Customizationクラスを作成し、Cultureプロパティに文字列を設定し、次のようにStartupに注入しました。

        // Load Custom Configuration from AppSettings.json
        services.Configure<Models.CustomSettings>(Configuration.GetSection("CustomSettings"));

IOptions customSettingsを挿入してアクセスすると、customSettings.Value.Cultureの値はNULLを返します。

最初の質問:I何が悪いのか、何が欠けていますか?

2番目の質問:HomeIndexのインデックスで以下を実行すると例外がスローされるのはなぜですか?

public class HomeController : Controller
{
   public IActionResult Index(IConfiguration configuration)
   {
   }
}

例外:

リクエストの処理中に未処理の例外が発生しました。 InvalidOperationException: 'Microsoft.Extensions.Options.IOptions`1 [[OmniMerchant.Models.CustomSettings、OmniMerchant、Version = 1.0.0.0、Culture = neutral、PublicKeyToken = null]]タイプのインスタンスを作成できませんでした。モデルにバインドされた複合型は、抽象型または値型であってはならず、パラメーターのないコンストラクターが必要です。

Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.CreateModel(ModelBindingContext bindingContext)

3番目の質問:appSettings.jsonのカルチャプロパティに基づいて、すべてのアプリのバックグラウンドで開始からカルチャを設定する必要があります MSDNドキュメント を読みましたが、それを達成できませんでした、¿方法これを達成できますか?

ありがとう

まず、appsettingセクションに一致するモーダルを作成します

public class CustomSettings
{
    public string Culture { get; set; }
}

次に、それをStartup.csのConfigureServicesメソッドに登録します。

services.Configure<CustomSettings>(Configuration.GetSection("CustomSettings"));

次に、必要に応じてIOptionsを使用して注入します

AccountController(IOptions<CustomSettings> settings)
{
    _settings = settings.Value;
}
7
Marcus Höglund
  1. 構成セクションの値がnullである理由

デフォルトでは、2つの構成ファイルがあります。リリースビルド用とデバッグ用。実際に正しいものを編集していることを確認しましたか(おそらくappsettings.Development.json

  1. DIが機能しない理由.

.NET Coreでは、基本的にDIを2つの方法で使用できます。それをコンストラクターまたはメソッドに直接注入する。 2番目のオプションでは、特別な属性 [[FromServices] を使用する必要があります

4
Thowk

TL:DR; appsettings.jsonファイルは、dllファイルと同じ作業ディレクトリにある必要があります。

アプリをその作業ディレクトリから実行していることを確認する必要があります。

たとえば、dllがbinフォルダーにビルドされている場合、以下は機能しません。

cd bin
dotnet run app.dll

なぜなら appsettings.jsonファイルが、実行中のdllと同じフォルダーにありません。

ただし、appsettings.jsonファイルがある場合、現在の作業ディレクトリが設定され、そのファイルが読み取られます。

dotnet run bin/app.dll

VSコードを使用する場合launch.jsoncwdプロパティを設定してこれを実現できます。

4
Darbio

アプリケーションのプロパティ->デバッグセクション->環境変数

これが設定されている場合ASPNETCORE_ENVIRONMENT:開発

appsettings.Development.jsonを使用します

4
Ryan Dobbs

以下のように、Startupコンストラクタに具体的に追加するまで、さまざまな構成ファイルからの読み取りに問題がありました。

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json")                //***
        .AddJsonFile("appsettings.development.json")    //***
        .AddEnvironmentVariables();

        Configuration = builder.Build();
}
2
Mircea Nemteanu

これは私が思うバグですが、おそらく「HostingEnvironment.ContentRootPath」を手動で設定することで解決できます。

Startup.csのStartupメソッドに次のコードを追加してみてください。

if (env.EnvironmentName== "Production")
{
    env.ContentRootPath = System.IO.Directory.GetCurrentDirectory();
}

またはこのようなハードコードパス:

if (env.EnvironmentName == "Production")
{
    env.ContentRootPath = "/var/aspnetcore/...";
}

たとえば、ファイルが "/ var/aspnetcore/my_ASP_app"にある場合、起動方法は次のようになります。

public Startup(IHostingEnvironment env)
{
    if (env.EnvironmentName== "Production")
    {
        //env.ContentRootPath = "/var/aspnetcore/my_ASP_app";
        env.ContentRootPath = System.IO.Directory.GetCurrentDirectory();
    }
    //env.ContentRootPath = System.IO.Directory.GetCurrentDirectory();//you can write this line outside of IF block.
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile("appsettings.Production.json", optional: true, reloadOnChange: true);

    Configuration = builder.Build();

}

ハードコーディングの代わりにDirectory.GetCurrentDirectory()を使用することをお勧めします。

これはLinux Ubuntnginxで私にとってはうまくいきましたが、あなたの環境に適用できるかどうかはわかりません。

0
Mostafa.A