Вручную скажите ASP.Net Core MVC, какой файл appsettings.environment.json взять - PullRequest
0 голосов
/ 08 сентября 2018

Мы разрабатываем приложение ASP.Net Core MVC 2. Наш специалист по настройке сказал мне, когда я настраивал проект, что мы не можем установить обычную системную переменную ASPNETCORE_ENVIRONMENT на наших боксах, потому что мы будем делиться с другими командами.

Итак, я начал искать способы ручного управления средой, в которой приложение ASP.Net Core MVC считает, что оно работает.

Я думал, что все готово и понял.

Это наша установка.

В моем файле appsettings.json у меня есть переменная настроек, которая называется "AARTS_ENVIRONMENT". (AARTS - название нашего проекта).

{
    "Settings": {
        "AARTS_ENVIRONMENT": "Staging",
        ...
    }
}

Далее у меня есть три файла json среды. Я просто поместил статический текст для connstring на данный момент для отладки.

appsettings.development.json

{
  "ConnectionStrings": {
    "AartsConnection" :  "DevConn"
  }
}

appsettings.staging.json

{
  "ConnectionStrings": {
    "AartsConnection" :  "StagingConn"
  }
}

appsettings.production.json

{
  "ConnectionStrings": {
    "AartsConnection" :  "ProdConn"
  }
}

Вот наш файл startup.cs.

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();

        var configEnvironment = Configuration.GetValue<string>("Settings:AARTS_ENVIRONMENT");
        env.EnvironmentName = configEnvironment;
        _environmentName = env.EnvironmentName;
    }

Эта строка:

var configEnvironment = Configuration.GetValue<string>("Settings:AARTS_ENVIRONMENT");

читает нашу среду из нашей настройки AARTS_ENVIRONMENT в нашем главном файле appsettings.json.

И эта строка задает для имени среды значение AARTS_ENVIRONMENT.

env.EnvironmentName = configEnvironment;

С этой настройкой мы можем достичь двух из трех наших целей.

1) Мы можем принимать решения в бритве с помощью помощников тегов среды:

<environment include="Development">
    <link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
    <link href="~/css/site-bundle.css" rel="stylesheet" />
    <link href="~/lib/font-awsome/css/font-awesome.css" rel="stylesheet" />
</environment>
<environment exclude="Development">
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"
          asp-fallback-href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
          asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
    <link href="~/css/site-bundle.min.css" rel="stylesheet" />
    <link href="~/lib/font-awsome/css/font-awesome.min.css" rel="stylesheet" />
</environment>

Здесь мы можем получить правильные версии CSS-файлов. Полная версия для разработки и свернутые версии для не разработки. Здесь принимаются правильные решения, отражающие значение, которое мы указали в настройках приложения AARTS_ENVIRONMENT.

2) Мы можем принимать решения на основе среды из кода C #.

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            //app.UseExceptionHandler("/Error");
            app.UseStatusCodePages();
            //app.UseBrowserLink();
        }
        else
        {
            //app.UseExceptionHandler("/Home/Error");
            app.UseExceptionHandler("/Error");
        }

Это отражает нашу собственную переменную среды и принимает правильный путь принятия решения.

Однако наша последняя цель не работает.

3) Загрузите и используйте правильный файл appsettings.environment.json на основе нашего пользовательского параметра AARTS_ENVIRONMENT.

Если я поставлю точку останова при запуске, мы увидим загруженные файлы json.

Я устанавливаю переменную среды в качестве примера:

enter image description here

Теперь я получаю правильную среду, так как у меня установлен Staging для AARTS_ENVIRONMENT в appsettings.json.

enter image description here

Но когда я смотрю на свой ConnString, он извлекает из неправильного файла appsettings.environment.json. Это тянет из dev, а не постановка.

enter image description here

Итак, я посмотрел на мой метод StartUp чуть ближе, и он выглядел как ситуация с курицей или яйцом. Я добавлял файл appsettings. {Env.EnvironmentName} .json в конструктор конфигурации, прежде чем я прочитал среду из нашего пользовательского параметра и установил имя env.environment для IHostingEnvironment.

Но как вам прочитать имя среды до того, как вы построите конфигурацию с помощью компоновщика конфигурации?

Так что я немного переделал стартап:

    public Startup(IHostingEnvironment env)
    {
        var preBuilder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json");
        var preConfiguration = preBuilder.Build();
        var configEnvironment = preConfiguration.GetValue<string>("Settings:AARTS_ENVIRONMENT");
        // var configEnvironment = Configuration.GetValue<string>("Settings:AARTS_ENVIRONMENT");
        env.EnvironmentName = configEnvironment;

        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddEnvironmentVariables()
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        Configuration = builder.Build();

        _environmentName = env.EnvironmentName;
    }

Я создал второй сборщик конфигурации под названием prebuilder, чтобы я мог читать переменную AARTS_ENVIRONMENT из appsettings.json

Затем я использую это значение среды для построения основной конфигурации для веб-приложения:

Теперь, если я поставлю точку останова в StartUp, я вижу, что она теперь читает в appsettings.staging.json:

enter image description here

Но когда я захожу на мою страницу http://localhost:49547/debug/connstring, она все равно говорит DevConn.

Вот мой контроллер отладки:

public class DebugController : Controller
{
    private IUtilities _utilities;
    public DebugController(IUtilities utilities,
        IConfiguration configuration)
    {
        _utilities = utilities;
        Configuration = configuration;
    }

    IConfiguration Configuration { get; }

    // Get current environment for debugging purposes.
    public IActionResult Environment()
    {
        ViewBag.CurrentEnv = _utilities.CurrentEnvironment;
        return View();
    }

    public IActionResult HostPath()
    {
        ViewBag.HostPath = _utilities.HostPath;
        return View();
    }

    public IActionResult ConnString()
    {

        string connString = Configuration["ConnectionStrings:AartsConnection"];

        ViewBag.Connstring = connString;
        return View();
    }
}

Мои утилиты довольно большие. Но вот конструктор:

    public Utilities(IHostingEnvironment hostingEnvironment,
        IAssignmentRepository assignmentRepo,
        IUserRepository userRepo, IHttpContextAccessor httpContextAccessor,
        IRecommendationRepository recommendationRepo,
        IFindingRepository findingRepo,
        IAuditRepository auditRepo,
        IAcdRepository acdRepo)
    {
        _hostingEnvironment = hostingEnvironment;
        _assignmentRepo = assignmentRepo;
        _userRepo = userRepo;
        _httpContextAccessor = httpContextAccessor;
        _recommendationRepo = recommendationRepo;
        _findingRepo = findingRepo;
        _auditRepo = auditRepo;
        _acdRepo = acdRepo;
    }

и вот соответствующие действия и свойства утилиты:

public string CurrentEnvironment => _hostingEnvironment.EnvironmentName;
    public string HostPath =>
        $"{_httpContextAccessor.HttpContext.Request.Scheme}://{_httpContextAccessor.HttpContext.Request.Host}{_httpContextAccessor.HttpContext.Request.PathBase}";

Есть ли способ заставить его загрузить правильный файл appsettings.environment.json, основываясь на этом? Я чувствую, что я очень близко.

...