Как публиковать специальные приложения в среде .Net?
В моем основном приложении .Net есть 3 файла appsettings
конкретной среды
![enter image description here]()
в project.json
меня есть настройка publishOptions
как это. (на основании предложения здесь)
"publishOptions": {
"include": [
"wwwroot",
"appsettings.development.json",
"appsettings.staging.json",
"appsettings.production.json",
"web.config"
]
},
У меня есть 3 соответствующих класса запуска, которые используют соответствующие appsettings
зависимости от среды
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: false, reloadOnChange: true);
Однако когда я публикую приложение, все 3 файла appsettings окажутся во всех средах. Как опубликовать файл настроек приложения для конкретной среды?
Ответы
Ответ 1
Если кто-то еще задается вопросом, как использовать разные наборы приложений для нескольких сред, здесь возможное решение.
dotnet publish --configuration [Debug|Release]
скопирует соответствующий файл appsettings.json в папку публикации, если *.csproj
имеет условную логику для этих файлов:
- Сначала в
.pubxml
профиля публикации .pubxml
(его можно найти в PublishProfiles
Properties
→ PublishProfiles
в Visual Studio) отключите включение всех файлов содержимого по умолчанию.
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<EnableDefaultContentItems>false</EnableDefaultContentItems>
</PropertyGroup>
- Затем укажите условную логику Debug/Release
<Choose>
<When Condition="'$(Configuration)' == 'Debug'">
<ItemGroup>
<None Include="appsettings.json" CopyToOutputDirectory="Always" CopyToPublishDirectory="Always" />
<None Include="appsettings.prod.json" CopyToOutputDirectory="Never" CopyToPublishDirectory="Never" />
</ItemGroup>
</When>
<When Condition="'$(Configuration)' == 'Release'">
<ItemGroup>
<None Include="appsettings.json" CopyToOutputDirectory="Never" CopyToPublishDirectory="Never" />
<None Include="appsettings.prod.json" CopyToOutputDirectory="Always" CopyToPublishDirectory="Always" />
</ItemGroup>
</When>
</Choose>
- Наконец внутри
Startup.cs
попробуйте загрузить оба файла
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile($"appsettings.prod.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
Я надеюсь, что это решение было полезным.
Ответ 2
Одним из возможных способов было бы запустить подготовительные или пост-публичные скрипты/команды, например, запустив задачу gulp, выполняющую dotnet publish-iis
(альтернативно, используя задачу в разделе prepublish
scripts
, чтобы скопировать файлы на перед публикацией.
Добавьте это в свой проект. json:
"scripts": {
"postpublish": [ "gulp cleanconfig", "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
}
Вы также можете запустить команду cmd или shell. Но на самом деле не должно быть никаких причин, по которым вы хотели бы сделать это в первую очередь, просто отправляйте все 3 файла appconfig, потому что, например, Azure App Service, вы можете переключать режим в зависимости от переменных среды, которые регулируются через Azure Portal, и при публикации, промежуточные и производственные слоты будут просто заменены, но остаются переменными окружающей среды.
Вы не должны хранить секреты в appsettings.json, хотя (я предполагаю, что вы делаете и почему хотите удалить файлы). Вместо этого используйте "секреты пользователя" для разработки и переменных среды для установки строк подключения и т.д. Для производства. Работает как шарм, особенно с Azure App Services и контейнерами докеров.
Ответ 3
В VS2017 Добавление нескольких окружений
шаги
щелкните правой кнопкой мыши проект → Добавить → NewItem - выберите json файл - напишите имя файла как "appsettings.staging.json" или "appsettings.production.json"
Добавить файл appsettings.staging.json
Результат Похоже на
Ответ 4
Недавно мне также пришлось найти решение для этого, и я достиг этого, добавив некоторые настройки в файл .csproj
и незначительное изменение в Program.cs
.
<Project Sdk="Microsoft.NET.Sdk.Web">
<!-- ... -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<EnvironmentName>Development</EnvironmentName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<EnvironmentName>Production</EnvironmentName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Stage|AnyCPU'">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<EnvironmentName>Staging</EnvironmentName>
</PropertyGroup>
<ItemGroup>
<Content Remove="appsettings.json" />
<Content Remove="appsettings.*.json" />
</ItemGroup>
<ItemGroup>
<Content Include="appsettings.json" CopyToOutputDirectory="PreserveNewest" />
<Content Include="appsettings.*.json" Exclude="appsettings.$(EnvironmentName).json" DependentUpon="appsettings.json" CopyToOutputDirectory="Never" />
<Content Include="appsettings.$(EnvironmentName).json" DependentUpon="appsettings.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<Target Name="RenameAppsettings" AfterTargets="Publish">
<Move SourceFiles="$(PublishDir)\appsettings.$(EnvironmentName).json" DestinationFiles="$(PublishDir)\appsettings.overrides.json" />
</Target>
</Project>
Чтобы объяснить это немного, я добавил элемент <EnvironmentName>
для каждой конфигурации, чтобы его можно было использовать в процессе сборки. Я использую appsettings.{EnvironmentName}.json
(т.е. appsettings.Staging.json
) просто как файл переопределения, поэтому я просто переименую нужный JSON файл в процессе сборки. Например, когда вы запускаете dotnet publish -c Stage
, он публикует файл appsettings.Staging.json
в папку publish и переименовывает его в appsettings.overrides.json
. В ваш Program.cs
вам также нужно будет просто включить файл appsettings.overrides.json
:
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.overrides.json", optional: true, reloadOnChange: true)
Я надеюсь, что это помогает!
Примечание: я включаю appsettings.*.json
и устанавливаю для него CopyToOutputDirectory="Never"
чтобы они все еще CopyToOutputDirectory="Never"
в Visual Studio при разработке. В противном случае, если вы хотите, чтобы текущий файл appsettings
среды отображался в VS, просто удалите эту строку из файла csproj
.
Ответ 5
Вам нужно фактически добавить переменные среды, согласно официальному учебнику:
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: false, reloadOnChange: true)
// do not forget to add environment variables to your config!
.AddEnvironmentVariables();
Ответ 6
Честно говоря, я считаю, что это не правильная задача для конвейера сборки. Также функции публикации dotnet cli очень ограничены. Идите к внешним инструментам, как показал вам Цзэн. Развертывание - это еще один домен с собственным набором сложностей, чем создание.
В dotnet cli нет встроенного метода вне использования внешних инструментов!
Ответ 7
Самый простой способ, который я нашел до сих пор, - развернуть все файлы конфигурации, а затем удалить дополнительные файлы после завершения развертывания.
Просто добавьте несколько дополнительных строк в конец оболочки развертывания или пакет script.
Ответ 8
Вы можете использовать условия MSBuild для необязательного включения файлов в выходные данные компиляции (или опубликованные выходные данные).
<ItemGroup Condition="'$(Configuration)'=='Release'">
<Content Remove="appsettings.Development.json;appsettings.Staging.json" />
<None Include="appsettings.Development.json;appsettings.Staging.json" />
</ItemGroup>
Вышеприведенное игнорирует варианты файла Development and Staging appsettings.json, когда целевой конфигурацией компиляции является Release.
Ответ 9
Я решил этот вопрос с помощью этого пакета Nuget: https://github.com/Microsoft/slow-cheetah/blob/master/doc/transforming_files.md
Это так просто для установки и использования всех конфигураций в конфигурации активного решения (в моем случае - я добавил новую "тестовую" конфигурацию для тестового развертывания).
После этого вы можете установить это расширение в VS: https://marketplace.visualstudio.com/items?itemName=vscps.SlowCheetah-XMLTransforms.
Только сейчас вы можете создать новые конфигурационные подфайлы для параметров конфигурации приложения .xml или .json в VS этим инструментом (как в руководстве). Например, у меня есть файлы Debug, Test, Release (appsettings.Debug.json и т.д.)
Следующий шаг - настройка профилей публикации для каждой конфигурации, и после публикации у вас будет только один файл со всеми необходимыми преобразованиями.
Преобразования работают как классическая трансформация среды .json в основных веб-приложениях .net.