Skip to content

How to Automatically Apply Shadow Copying Settings When Publishing ASP.NET Core Sites

TLDR

  • Shadow Copying resolves the issue where DLLs are locked during ASP.NET Core execution, preventing updates.
  • By pre-configuring web.config in the project root, settings are automatically merged during publishing, eliminating the need for manual server-side file modifications.
  • It is recommended to use the dotnet publish command combined with a pre-configured web.config to achieve CI/CD automated deployment.
  • Hosting Bundle 7.0+ uses enableShadowCopy; version 6.0 requires experimentalEnableShadowCopy.
  • The Shadow Copying mechanism automatically cleans up old folders; it is not a version management tool and should not be relied upon to retain old versions.
  • Always manually clean up the Shadow Copying folder after upgrading the .NET version, otherwise, it will trigger a 500.30 error.
  • Avoid writing files or logs within the application directory to prevent frequent and unnecessary application restarts.

Solving the DLL Locking Issue During Publishing

When you encounter this issue: When a web application is running, IIS locks the relevant DLL files, making it impossible to overwrite files when deploying a new version, requiring the application pool to be stopped manually.

The Shadow Copying mechanism copies application files to a temporary location for execution, thereby releasing the lock on the original deployment directory. The traditional approach involves manually modifying the web.config on the server, which is not suitable for CI/CD workflows.

The best practice is to pre-create a web.config in the project root. During publishing, the system will automatically use it as a base for merging.

Configuration Example

Add handlerSettings to the web.config in the project root:

xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\WebApi.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess">
        <handlerSettings>
          <handlerSetting name="enableShadowCopy" value="true" />
          <handlerSetting name="shadowCopyDirectory" value="../ShadowCopy/" />
        </handlerSettings>
      </aspNetCore>
    </system.webServer>
  </location>
</configuration>

If you need to set environment variables (such as ASPNETCORE_ENVIRONMENT) simultaneously, you can set them directly in the .pubxml, and they will be automatically merged into web.config after publishing:

xml
<EnvironmentName>Staging</EnvironmentName>

Execute the publish command:

bash
dotnet publish -c Release -p:EnvironmentName=Staging

Version Differences

  • Hosting Bundle 7.0.0 and above: Use the enableShadowCopy parameter.
  • Hosting Bundle 6.0.0: Use the experimentalEnableShadowCopy parameter.

Regarding the Folder Management Mechanism of Shadow Copying

When you encounter this issue: When developers mistakenly believe that Shadow Copying automatically maintains multiple versions for rollback purposes.

According to the AspNetCoreModuleV2 source code analysis, Shadow Copying is not designed as a version management tool. Once the system selects a new serial number folder as the execution path, it starts a thread to delete all other folders in that directory. If multiple folders are found coexisting in the directory, it is usually because the cleanup thread has not finished, or old files were locked, causing the deletion to fail.

Precautions

  • Upgrading .NET Version: After upgrading, you must manually delete the old Shadow Copying folder; otherwise, it will cause IIS to return a 500.30 error, and the Event Viewer will show a directory_iterator path not found exception.
  • Avoid Writing Files: You should avoid writing files or logs in the application directory; otherwise, every file change may trigger the Shadow Copying mechanism, leading to unnecessary application restarts.

Change Log

  • 2025-03-18 Initial document creation.
  • 2025-04-08 Added information on Shadow Copying anomalies caused by .NET version upgrades.
  • 2025-06-27 Added precautions regarding avoiding file writes in the application directory when using Shadow Copying.
  • 2026-01-22 Added common misconceptions and source code explanations regarding the Shadow Copying folder management mechanism.