.NET Core include folder in publish
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In .NET, publishing is not the same thing as building. A normal build creates binaries for development, while dotnet publish prepares the files that should actually ship. If you want an extra folder to appear in the published output, you need to mark it as publishable content in the project file.
What dotnet publish Includes by Default
ASP.NET Core projects already publish certain assets automatically, especially files under wwwroot. That is why static files such as CSS, JavaScript, and images usually show up without any extra configuration.
Other folders are not guaranteed to be copied unless the project file tells MSBuild what to do with them. The behavior depends on the item type:
- '
Compileitems are source code files' - '
Contentitems are deployable assets' - '
Noneitems exist in the project but are not copied unless you opt in'
If you have a custom folder like Templates, DataFiles, or Scripts, you usually want to treat it as Content.
The Most Common Project File Fix
Use a wildcard in the .csproj file and set CopyToPublishDirectory:
That tells MSBuild to include every file under Templates when publishing. PreserveNewest means files are copied only when needed. If you always want them recopied, use Always.
You can test it with:
Then inspect the publish directory and confirm the folder is present.
CopyToOutputDirectory Versus CopyToPublishDirectory
This difference confuses many developers.
CopyToOutputDirectory controls whether files appear in the normal build output, such as bin/Debug/net8.0.
CopyToPublishDirectory controls whether files appear in the publish output.
Sometimes you need both:
That is useful when the application needs the files during local runs and in deployment packages.
When wwwroot Is Enough
If the folder contains publicly served static files, placing it under wwwroot is often the cleanest solution:
ASP.NET Core already knows how to serve these files through static file middleware, and publish will include them automatically.
If the folder contains private templates, configuration fragments, seed data, or generated assets that should not be publicly reachable, keep it outside wwwroot and include it explicitly through the project file instead.
A Small Runtime Example
Suppose you publish email templates and read them from disk at runtime:
This code only works after publish if the file was copied into the output. That is why the .csproj change matters.
Choosing Include or Update
Use Include when the files are not already in the project items.
Use Update when the SDK already includes them and you only want to change metadata:
That distinction keeps the project file cleaner and avoids duplicate item declarations.
Common Pitfalls
One common mistake is adding CopyToOutputDirectory and assuming publish will behave the same way. Build output and publish output are related, but they are not identical.
Another mistake is putting private runtime files under wwwroot. That makes deployment easy, but it may expose internal assets over HTTP.
A third issue is forgetting wildcards. If you include only the folder name instead of Folder\**\*, MSBuild may not copy the files inside it.
Summary
- '
dotnet publishonly includes files that MSBuild knows should be published.' - '
wwwrootis automatically published for static web assets.' - Custom folders should usually be marked as
ContentwithCopyToPublishDirectory. - '
CopyToOutputDirectoryaffects build output, whileCopyToPublishDirectoryaffects publish output.' - Keep private runtime files outside
wwwrootand include them explicitly in the.csproj.

