How to publish environment specific appsettings in .Net core app?

后端 未结 12 2425
刺人心
刺人心 2020-12-04 15:33

I have 3 environment specific appsettings files in my .Net core application

in project.json I have setup publishOptions

相关标签:
12条回答
  • 2020-12-04 16:01

    I solved this question with this nuget package: https://github.com/Microsoft/slow-cheetah/blob/master/doc/transforming_files.md

    It`s so easy for installation and using all configurations in Active solution configuration (In my case - I added a new "Test" configuration for test deployment).

    After this you can install this extension in VS: https://marketplace.visualstudio.com/items?itemName=vscps.SlowCheetah-XMLTransforms.

    Just now you can create a new config subfiles for .xml or .json application configuration settings in VS by this tool (as in manual). For example, I has Debug, Test, Release files (appsettings.Debug.json and etc.)

    Next step - setting up the publish profiles for each configuration and after publishing you will have only one file with all the necessary transformations.

    Transformations works like a classic .json envinronment transormation in .net core web applications.

    0 讨论(0)
  • 2020-12-04 16:06

    I have this same problem because I need to switch between different production configuration files due to multiple sites using the same codebase.

    In the end, I created a powershell script for each client/site. The script copies a client-specific configuration file over the production configuration file, then runs the publish. I actually do this for both the appSettings.json file and the environment.ts file. The script looks a bit like this:

    Remove-Item –path ClientApp\src\environments\environment.prod.ts
    Remove-Item –path appsettings.production.json
    Write-Output "--> config files removed"
    Copy-Item -path ClientApp\src\environments\environment.CLIENT-SITE-NAME.ts ClientApp\src\environments\environment.prod.ts
    Copy-Item -path appsettings.CLIENT-SITE-NAME.json appsettings.production.json
    Write-Output "--> config files copied"
    dotnet build MYPROJ.csproj -c Release /p:DeployOnBuild=true /p:PublishProfile=CLIENT-SITE-NAME 
    Write-Output "--> built & published"
    Remove-Item –path ClientApp\src\environments\environment.prod.ts
    Remove-Item –path appsettings.production.json
    Write-Output "Finished"
    

    In each of my client sites' .pubxml files, I exclude ALL the non-production appsettings from being published, like so:

    <ItemGroup>
      <Content Update="appsettings.json" CopyToPublishDirectory="Never" />
      <Content Update="appsettings.site1.json" CopyToPublishDirectory="Never" />
      <Content Update="appsettings.site2.json" CopyToPublishDirectory="Never" />
      <Content Update="appsettings.development.json" CopyToPublishDirectory="Never" />
    </ItemGroup>
    

    I remove the production files in the end to make sure I don't accidentally deploy them to the wrong site using the Publish wizard.

    (I store the password in the pubxml file, but you could include it in the script as a parameter as an alternative)

    0 讨论(0)
  • 2020-12-04 16:11

    Honestly I think that is not the right task for a build pipeline. Also the publishing features of the dotnet cli are very limited. Go to external tools like Tseng showed you. Deployment is another domain with an own set of complexity than building.

    There is not a build in way on dotnet cli beyond using external tools!

    0 讨论(0)
  • 2020-12-04 16:14

    If someone else is wondering how to use different appsettings for multiple environments here is a possible solution.

    dotnet publish --configuration [Debug|Release] will copy the appropriate appsettings.json file into the publish folder if *.csproj has a conditional logic for these files:

    • First in the .pubxml publish profile file (can be found in Properties->PublishProfiles of Visual Studio) disable that all content files are included by default
    <PropertyGroup>
        <TargetFramework>netcoreapp2.1</TargetFramework>
        <EnableDefaultContentItems>false</EnableDefaultContentItems>
    </PropertyGroup>
    
    • Then specify conditional Debug/Release logic
    <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>
    
    • Finally inside Startup.cs try to load both files
    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();
    }
    

    I hope this solution, has been helpful.

    0 讨论(0)
  • 2020-12-04 16:14

    The easiest way i have found so far is to deploy all config files and then remove extra files after the deployment is finished. Just add few extra lines at the end of your deployment shell or batch script.

    0 讨论(0)
  • 2020-12-04 16:14
            Consider you have multiple appsettings: dev,pre,prod. 
        You can have below configuration in your web project file.
    
             <!-- This configuration is done for dotnet publish command.
         It will make sure only environment specific files will be copied -->
              <ItemGroup Condition=" '$(EnvironmentName)' == 'Dev'">
                <Content Remove="appsettings.Prod.json" />
                <Content Remove="appsettings.Pre.json" />
              </ItemGroup>
              <ItemGroup Condition=" '$(EnvironmentName)' == 'Pre'">
                <Content Remove="appsettings.Prod.json" />
                <Content Remove="appsettings.Dev.json" />
                <Content Remove="appsettings.Development.json" />
              </ItemGroup>
              <ItemGroup Condition=" '$(**EnvironmentName**)' == 'Prod'">
                <Content Remove="appsettings.Pre.json" />
                <Content Remove="appsettings.Dev.json" />
                <Content Remove="appsettings.Development.json" />
              </ItemGroup>
    
            This confguration will help during publish. 
        It will not copy the appsettings which is not required for that environment.
    
            EnvironmentName (part of  <ItemGroup Condition=" '$(**EnvironmentName**)' == 'Prod'">) 
    highlighted above should be passed as parameter in below command.
    
            dotnet publish -o ../../published/20191118A -c release /p:EnvironmentName=Development
    
    0 讨论(0)
提交回复
热议问题