appSettings.json中的自定义键无法在ASP.NET Core 2.0

时间:2018-01-24 18:27:22

标签: c# asp.net asp.net-core-2.0

我在ASP.NET Core项目的appSettings.json中添加了一个CustomSettings部分键:

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

我无法在以下控制器中加载Culture键:

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”)[ “文化”]; configuration.GetSection( “CustomSettings”)的GetValue( “文化”);

我尝试了基于ASP.NET Core: Step by Step Guide to Access appsettings.json in web project and class library的帮助,我创建了带有字符串Culture属性的CustomSettings类,并在Startup中注入如下:

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

通过注入IOptions customSettings来访问,值为 customSettings.Value.Culture返回NULL。

第一个问题:¿我做错了什么或缺少什么?

第二个问题:¿为什么在HomeController的索引中执行以下操作会引发异常?

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)

第三个问题:我需要根据appSettings.json上的Culture属性为后台的所有应用设置文化,我阅读MSDN documentation,但我无法实现,¿怎么能我实现了这个目标吗?

由于

6 个答案:

答案 0 :(得分:7)

首先创建与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;
}

答案 1 :(得分:4)

  1. 为什么配置节值为空?
  2. 默认情况下,有两个配置文件。对于Release构建和一个用于Debug。您是否检查过您实际编辑的是正确的(可能是 appsettings.Development.json

    1. 为什么DI不起作用。
    2. 在.NET Core中,您基本上可以通过两种方式使用DI。通过在构造函数中或直接在方法中注入它。在第二个选项中,您必须使用特殊属性[FromServices]

答案 2 :(得分:4)

在您的应用程序属性中 - &gt;调试部分 - &gt;环境变量

如果设置了此项 ASPNETCORE_ENVIRONMENT:发展

它将使用appsettings.Development.json

答案 3 :(得分:3)

TL:DR; 您的appsettings.json文件必须与dll文件位于同一工作目录中。

您需要确保从其工作目录中运行该应用。

例如,如果您的dll是建立在bin文件夹中的,则以下操作将不起作用:

cd bin
dotnet run app.dll

因为appsettings.json文件与您正在运行的dll不在同一文件夹中。

但是,如果您位于appsettings.json文件所在的目录中,则将设置当前工作目录并读取该文件。

dotnet run bin/app.dll

如果使用VS Code launch.json,则可以设置cwd属性以实现此目的。

答案 4 :(得分:2)

我在从不同的配置文件中读取时遇到了问题,直到我在Startup构造函数中专门添加了每个配置文件,如下所示:

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

        Configuration = builder.Build();
}

答案 5 :(得分:0)

这是我认为的错误,但您可以通过手动设置“ 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(),而不是硬编码。

这在 nginx Linux Ubuntu 中对我有用,但是我不知道它是否适合您的环境。