.NET Core 6 Found multiple publish output files with the same relative path

Viewed 6296

I'm running into a relatively new issue on .NET Core 6 where when publishing with Web Deploy via Visual Studio 2022. I'm receiving the following error:

Error Found multiple publish output files with the same relative path: C:\Work\MySolution\A\appsettings.json, C:\Work\MySolution\B\appsettings.json, C:\Work\MySolution\A\appsettings.Staging.json, C:\Work\MySolution\B\appsettings.Staging.json, , C:\Work\MySolution\A\appsettings.Development.json, C:\Work\MySolution\B\appsettings.Development.json

There is no issues when building, just publishing.

I have two ASP.NET Core 6 projects. Project "A" references project "B" (I know B should really be a class library, but go with me).

I am aware that this is expected functionality in .NET Core 6 (https://docs.microsoft.com/en-us/dotnet/core/compatibility/sdk/6.0/duplicate-files-in-output). However, I cannot seem to tell project "A" to ignore project "B" appsettings files. I am aware of the ErrorOnDuplicatePublishOutputFiles property I can set, but I'm trying to strictly tell it not to include those files.

Here's some examples of items that I have tried, but does not work.

Example 1: Tried typical content update approach (supposedly does not work after VS 15.3). Also tried with absolute paths.

A.csproj

...

<ItemGroup>
  <ProjectReference Include="..\B\B.csproj">
    <PrivateAssets>all</PrivateAssets>
  </ProjectReference>
</ItemGroup>
  
<ItemGroup>    
  <Content Update="..\B\appsettings.json" CopyToOutputDirectory="Never" CopyToPublishDirectory="Never" />
  <Content Update="..\B\appsettings.*.json" CopyToOutputDirectory="Never" CopyToPublishDirectory="Never" />
</ItemGroup>

...

Example 2: Tried typical content remove approach. Also tried with absolute paths.

A.csproj

...

<ItemGroup>
  <ProjectReference Include="..\B\B.csproj">
    <PrivateAssets>all</PrivateAssets>
  </ProjectReference>
</ItemGroup>
  
<ItemGroup>    
  <Content Remove="..\B\appsettings.json" />
  <Content Remove="..\B\appsettings.*.json" />
</ItemGroup>

<ItemGroup>    
  <None Include="..\B\appsettings.json" />
  <None Include="..\B\appsettings.*.json" />
</ItemGroup>

...

Example 3: I tried using the GeneratePathProperty path to make sure it was directly ignoring project B's files.

A.csproj

...

<ItemGroup>
  <ProjectReference Include="..\B\B.csproj" GeneratePathProperty="true">
    <PrivateAssets>all</PrivateAssets>
  </ProjectReference>
</ItemGroup>
  
<ItemGroup>    
  <Content Update="$(PkgB)\appsettings.json" CopyToPublishDirectory="Never" />
  <Content Update="$(PkgB)\appsettings.*.json" CopyToPublishDirectory="Never" />
</ItemGroup>

...

Example 4: Modified pubxml to ignore specific files. Tried with absolute paths too.

A.pubxml

...

<ExcludeFilesFromDeployment>..\B\appsettings.json;..\B\appsettings.Staging.json;...</ExcludeFilesFromDeployment> 

...

Example 5: Modified pubxml file to explicity ignore project B files. Tried absolute paths as well.

A.pubxml

...

<ItemGroup>
  <ResolvedFileToPublish Include="..\B\appsettings.json">
    <CopyToPublishDirectory>Never</CopyToPublishDirectory>
  </ResolvedFileToPublish>
  <ResolvedFileToPublish Include="..\B\appsettings.Staging.json">
    <CopyToPublishDirectory>Never</CopyToPublishDirectory>
  </ResolvedFileToPublish>
  <ResolvedFileToPublish Include="..\B\appsettings.Development.json">
    <CopyToPublishDirectory>Never</CopyToPublishDirectory>
  </ResolvedFileToPublish>
  <ResolvedFileToPublish Include="..\B\appsettings.Backup.json">
    <CopyToPublishDirectory>Never</CopyToPublishDirectory>
  </ResolvedFileToPublish>
</ItemGroup>

...

I've tried various other combos, but none of it seems to work...

  • Windows 10
  • Visual Studio 2022 (latest)
  • .NET Core 6
2 Answers

I ran into this problem upgrading .NET 5 web services to .NET 6. As the link you provided points out, this is by design now. I fixed it by renaming the appsettings.json file in both projects by prepending the assembly name, and then reconfiguring the configuration (yes, that's a thing) as follows:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureAppConfiguration((context, configBuilder) =>
            {
                string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
                string envName = context.HostingEnvironment.EnvironmentName;
                configBuilder.Sources.Clear();
                configBuilder.AddJsonFile($"{assemblyName}.appsettings.json", optional: false, reloadOnChange: true);
                configBuilder.AddJsonFile($"{assemblyName}.appsettings.{envName}.json", optional: true, reloadOnChange: true);
            });
            webBuilder.UseStartup<Startup>();

As you can see, our code is still ".NET 5-style" at this point.

I ran into this issue with a web application that had a Razor Class Library. The Culprit file was LIBMAN.JSON.

Change the properties of the file to:

Build Action: NONE

Copy to Output Directory: DO NOT COPY

Other files that are used for tooling only could possibly be changes the same way.

Related