.NET Core 2.0控制台应用发布缺失appsettings及配置合并问题
Hey Colin, let's tackle these two .NET Core console app deployment hurdles you're facing—they’re super common when shifting from .NET Framework to Core, so you’re definitely not alone here!
Problem 1: Publish doesn’t include appsettings files (unlike ASP.NET Core)
By default, .NET Core console apps don’t automatically copy appsettings.json or its environment-specific variants to the publish directory. Fix this by updating your .csproj file to explicitly mark these files for publication:
<ItemGroup> <!-- Ensure main appsettings is copied to publish output --> <Content Include="appsettings.json"> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> <!-- Include environment-specific files temporarily (we'll clean them up later) --> <Content Include="appsettings.*.json"> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup>
This ensures all your config files make it to the publish folder during the build step, which sets us up for the next part.
Problem 2: Merge environment-specific config into main appsettings.json (no runtime merging)
Since you want to avoid deploying multiple config files and runtime resolution ambiguity, the best approach is to merge configs at build time—so your final artifact only contains a single appsettings.json with all environment-specific values already applied. Here are two reliable methods:
Method 1: Use MSBuild’s TransformXml Task (built-in, no extra tools)
This leverages the same transformation logic Slow Cheetah uses, adapted for .NET Core. Add this target to your .csproj file:
<!-- Import the TransformXml task (works for .NET Core too) --> <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" /> <Target Name="MergeEnvironmentAppSettings" BeforeTargets="Publish"> <!-- Define paths based on your target environment --> <PropertyGroup> <MainConfig>appsettings.json</MainConfig> <EnvironmentConfig>appsettings.$(EnvironmentName).json</EnvironmentConfig> <FinalConfig>$(PublishDir)appsettings.json</FinalConfig> </PropertyGroup> <!-- Merge the environment config into the main config --> <TransformXml Source="$(MainConfig)" Transform="$(EnvironmentConfig)" Destination="$(FinalConfig)" /> <!-- Delete all environment-specific config files from the publish directory --> <Delete Files="$(PublishDir)appsettings.*.json" /> </Target>
When you publish, specify your target environment via MSBuild property:
dotnet publish --configuration Release /p:EnvironmentName=Dev
This will:
- Merge
appsettings.Dev.jsoninto the mainappsettings.jsonin the publish folder - Delete all other
appsettings.*.jsonfiles, leaving only the merged, environment-ready config
Method 2: Use a dotnet CLI tool (simpler for scripted CI/CD)
If you prefer a CLI-first approach, use the dotnet-config-transform tool:
- Install the tool globally:
dotnet tool install -g dotnet-config-transform - In your CI/CD script, after publishing, run the merge command and clean up:
# Publish the app first dotnet publish --configuration Release --output ./publish # Merge environment config into main config dotnet config-transform merge ./publish/appsettings.json ./appsettings.Dev.json --output ./publish/appsettings.json # Delete environment-specific config files rm ./publish/appsettings.*.json
Key Benefits of This Approach
- No runtime ambiguity: Your deployed
appsettings.jsonis a single source of truth—no guessing which configs are being merged at runtime. - Secure artifact deployment: Each environment gets only its own config, eliminating the risk of exposing other environment settings.
- Familiar workflow: Aligns with your existing Slow Cheetah transformation process, just adapted for .NET Core.
内容的提问来源于stack exchange,提问作者Colin Mackay

