Reputation: 4000
When I issue the following command in the command line:
dotnet publish -o "./../output" -c Release
The dotnetcli
publishes the project correctly. However, it does not copy the appsettings.Production.json
file, only the appsettings.json
.
Why is this? I have googled around and read the official core docs, but haven't found how the correct environment appsettings.json
is supposed to end up in the publish output.
Should I copy appsettings.Production.json
manually to the published folder?
Upvotes: 89
Views: 93298
Reputation: 71
Whether or not appsettings*.json are included is also a behavior that is part of the used sdk. Defined in the csproj file. Microsoft.NET.Sdk.Web copies *.json and *.config by default. Microsoft.NET.Sdk does not.
Upvotes: 1
Reputation: 119
I am using VS 2022, but this works for 2019 as well. I was having the same issue with my debug/release configurations. I wanted only to publish appsettings.json during a release publish, but the appsetting.Development.json was always copied as well. With a bit of searching, I found the choose/when option.
<Choose><When Condition=""></When></Choose>
With two When sections, one for Debug and one for Release I was able to accomplish this beautifully.
<Choose>
<When Condition="'$(Configuration)' == 'Debug'">
<ItemGroup>
<Content Include="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
</When>
<When Condition="'$(Configuration)' == 'Release'">
<ItemGroup>
<Content Remove="appsettings.Development.json" />
</ItemGroup>
</When>
</Choose>
I hope this helps.
ref: https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-conditional-constructs?view=vs-2022
Upvotes: 7
Reputation: 133
I found that you don't need to manually modify the project file to add in the items. Just set the "Build Action" to "Content" for these items in file properties. They get copied to the build output AND the publish folder. They're also included in the Application Files folder with the .deploy extension if you're publishing for ClickOnce.
Upvotes: 1
Reputation: 1945
Discovered a three-step build in Visual Studio approach for publishing environment-specific appsetting files (Windows, PowerShell).
This approach will publish
Step 1. Update csproj:
<!-- App Settings -->
<ItemGroup>
<Content Remove="appsettings.json" />
<Content Remove="appsettings.*.json" />
</ItemGroup>
<ItemGroup>
<Content Include="appsettings.json" CopyToOutputDirectory="Always" />
<Content Include="appsettings.$(ASPNETCORE_ENVIRONMENT).json" DependentUpon="appsettings.json" CopyToOutputDirectory="Always" />
</ItemGroup>
Step 2. Set an environment variable in PowerShell:
# Read
[Environment]::GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "User")
# Output: empty string if not set or 'Staging' in my case
# Set environment variable "User" or "Machine" level
[Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Staging", "User")
Step 3. Then close and reopen Visual Studio solution to enable Visual Studio to see the environment variable and reload project structure accordingly.
Final step. Run publishing.
Note: publishing profile environment variables do not affect publishing configuration. This approach uses PowerShell to set an environment variable and enables environment-specific publishing. Please see link for more details on environment variables.
Upvotes: 6
Reputation: 171
VS 2019 (Version 16.4.1) has option to publish only the appsettings.json
on right click on the file:
It will take your connection from the publish profile.
Upvotes: 1
Reputation: 7353
After Visual Studio 2017 15.3
Edit the .csproj file to manually exclude files/folder from being published
<ItemGroup>
<Content Remove="appsettings.Development.json" />
</ItemGroup>
Upvotes: 10
Reputation: 49789
Update:
For current (new) .csproj format the CopyToPublishDirectory
attribute should be used. It determines whether to copy the file to the publish directory and can have one of the following value:
So add next section into your .csproj
:
<ItemGroup>
<None Include="appsettings.Production.json" CopyToPublishDirectory="Always" />
</ItemGroup>
Look into @nover answer and SO Exclude or include files on publish for more information about file's control during publishing.
"In your project.json
file you have the section publishOptions
with subsection include
, where you already have some files like "appsettings.json":
"publishOptions": {
"include": [
"appsettings.json",
"hosting.json",
"project.json",
"web.config"
]
},
You should add "appsettings.Production.json"
into this array.
Updates based on comments:
Keep in mind, that all the appsettings.*.json
files like appsettings.development.json
, appsettings.staging.json
and appsettings.production.json
will always end up in all environments. You cannot simply handle this using project.json
, as it does not support any condition rules. This will be changed in future, when project.json
will be replaced back to msbuild
and .csproj
. If this is critical for your app, consider to use another configuration store, like Environment Variable, database, etc.
Note, that order is important, as determine which settings will be applied if they exist in multiple locations. From documentation:
The order in which configuration sources are specified is important, as this establishes the precedence with which settings will be applied if they exist in multiple locations. In the example below, if the same setting exists in both appsettings.json and in an environment variable, the setting from the environment variable will be the one that is used. The last configuration source specified “wins” if a setting exists in more than one location. The ASP.NET team recommends specifying environment variables last, so that the local environment can override anything set in deployed configuration files.
Upvotes: 114
Reputation: 2369
For the new csproj
project format you have to add a new ItemGroup
with the content
<ItemGroup>
<Content Include="appsettings.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="appsettings.Production.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
In case you have multiple appsettings.{env}.json
files simply repeat the Content
tag inside the same ItemGroup
and all your settings files will end up in the publish folder.
As mentioned in the comments an even cleaner solution is to use a wildcard include:
<ItemGroup>
<Content Include="appsettings*json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
And all your appsettings
files will be published!
Upvotes: 19
Reputation: 5413
In your project.json
there is a section publishOptions
. This lists all the files and folders that will be included when you publish. You will need to update yours to look something like this
{
"publishOptions": {
"include": [
"wwwroot",
"Views",
"appsettings.json",
"appsettings.Production.json",
"web.config"
]
},
}
You can also use globbing patterns, so you should find this works too (I haven't tested this one)
{
"publishOptions": {
"include": [
"wwwroot",
"Views",
"appsettings*.json",
"web.config"
]
},
}
Upvotes: 17