Search code examples
.netasp.net-core.net-coredotnet-publish

Dotnet publish copies appsettings*.json only for Asp.Net (but not Console)


I am running dotnet publish (via VS2019 GUI or a command, same result) on an ASP.Net project and on a Console project.

It seems that behaviour differs. All appsettings*.json are being copied automatically in ASP.Net, but on console only if I set them to <CopyToOutputDirectory>Always</CopyToOutputDirectory>.

Is this some kind of a bug or is it really designed to be different depending on project type?

The behavior looks a bit odd to me.


Solution

  • If you compare the .csproj files for both projects, you will notice that the ASP.NET Core project references an SDK Microsoft.NET.Sdk.Web while the console project just references Microsoft.NET.Sdk. The SDK is basically a pre-defined set of configurations and defaults to make working with ASP.NET Core or console applications simple and the project file easy to read and maintain.

    The Microsoft.NET.Sdk.Web actually extends the Microsoft.NET.Sdk so everything the latter SDK does is also included in the Web SDK. The Web SDK just adds some more ASP.NET Core related stuff. This also means that a web application is just a console application.

    One of the lines the Web SDK contains that are not included in the general SDK is the following:

    <Content Include="**\*.json" CopyToPublishDirectory="PreserveNewest" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(DefaultWebContentItemExcludes)" />
    

    This basically defines all .json files as content that should be copied to the publish directory. So basically this is exactly what makes ASP.NET Core projects copy the appsettings.json files to the publish directory.

    Since this is not part of the normal project SDK, console applications will not automatically copy appsettings.json files to the publish directory. This is generally intentional because raw console applications are not necessarily built upon the configuration system that uses these files.

    It is possible (and it becomes probably more relevant in the future with the generic host in 3.0) but not a default. So if you want to copy the files to the publish directory, then you should add that rule yourself to your .csproj:

    <ItemGroup>
        <Content Include="*.json" CopyToPublishDirectory="PreserveNewest" />
    </ItemGroup>
    

    Btw. since you mentioned in the comments that ASP.NET Core doesn’t really require appsettings.json files itself (which is absolutely true), the Web SDK does expose two properties EnableDefaultItems and EnableDefaultContentItems to disable this default behavior (along with a few others).