75

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?

Set
  • 40,147
  • 18
  • 114
  • 133
peco
  • 3,510
  • 1
  • 18
  • 24
  • See [this answer](https://stackoverflow.com/a/54216774/10685590) for a possible solution of environment specific appsettings. – Ben Jan 16 '19 at 12:20

6 Answers6

97

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:

  • Always,
  • PreserveNewest
  • Never

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.

Jerodev
  • 29,019
  • 11
  • 72
  • 94
Set
  • 40,147
  • 18
  • 114
  • 133
  • 3
    Why do you need `project.json` to be published at all? – Pawel Jun 16 '16 at 20:44
  • 3
    But it doesn't merge a setting based on publish profile? It always reads the key which is in appsettings.json, not appsetting.release.json. – Barbaros Alp Aug 10 '16 at 11:04
  • In my case, settings from the publish profile actually get merged with my appsettings.Production.json @BarbarosAlp – Riscie Aug 11 '16 at 07:39
  • 4
    does that mean all the appsettings files like `appsettings.development.json`, `appsettings.staging.json` and `appsettings.production.json` will always endup in all the environment? – LP13 Aug 31 '16 at 17:42
  • project.json is phased out, not appsettings.json ! – Softlion Oct 24 '16 at 18:44
  • The CopyToPublishDirectory attribute in the .csproj file doesn't copy anything! So this doesn't work. – ygoe Dec 05 '17 at 13:37
  • @ygoe it works for me with `dotnet publish`... You may create a SO question and describe your problem – Set Dec 05 '17 at 13:45
17

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"
    ]
  },
}
Sock
  • 4,963
  • 19
  • 29
15

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!

nover
  • 1,824
  • 22
  • 24
  • 3
    You also can take advantage of wildcards, and use the single node with `Include="appsettings*json"`. You can do it manually. – stukselbax Jul 05 '17 at 05:15
  • nice one @stukselbax - incorporated your feedback in my response – nover Jul 05 '17 at 14:04
  • 1
    Doesn't work. The build error says these files are already defined elsewhere. Seems the default behaviour can't be overwritten. – ygoe Dec 05 '17 at 13:35
  • 1
    @ygoe yes this is something new in the dotnet toolchain - the build tools are considering them as implicitly included. – nover Dec 06 '17 at 13:41
8

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>

ref: https://www.danielcrabtree.com/blog/273/fixing-the-duplicate-content-error-after-upgrading-visual-studio-2017

original source

Ben Anderson
  • 6,123
  • 4
  • 36
  • 39
3

Discovered a three-step build in Visual Studio approach for publishing environment-specific appsetting files (Windows, PowerShell).

  • appsettings.json
  • appsettings.Development.json
  • appsettings.Staging.json
  • appsettings.Production.json

This approach will publish

  • appsettings.json and
  • appsettings.$(ASPNETCORE_ENVIRONMENT).json.

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.

  • Now appsettings.json is a parent and appsettings.Staging.json is a nested file.
  • If you set another environment (for example "Production") and then close and Visual Studio and reopen your solution, then you will appsettings.json as a parent and appsettings.Production.json as a nested file.

enter image description here

Final step. Run publishing.

enter image description here

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.

enter image description here

Anton Lyhin
  • 1,817
  • 2
  • 26
  • 33
0

VS 2019 (Version 16.4.1) has option to publish only the appsettings.json on right click on the file:

publish-json

It will take your connection from the publish profile.

Dharman
  • 21,838
  • 18
  • 57
  • 107
marinoff
  • 71
  • 2
  • 5