.NET Core
.NET Standard
project files
exclude files
development tips

How do I exclude files/folders from a .NET Core/Standard project?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

SDK-style .NET projects automatically include many files, which is convenient until a folder should stay in the repository but out of the build. The fix is usually in the .csproj file, not in your IDE view and not in .gitignore. Once you know which MSBuild item type owns a file, exclusions become straightforward.

Understand What the SDK Includes Automatically

Modern .csproj files are convention-based. A new .cs file often compiles without any manual project-file change because the SDK includes it by default.

The main item types you will work with are:

  • 'Compile for source files'
  • 'Content for assets copied or published with the app'
  • 'None for files that belong to the project but are not compiled'

That distinction matters because removing a path from the wrong item type has no effect. When a file keeps showing up in build or publish output, the first question is not "is my wildcard correct." It is "which item type currently includes this file."

Exclude Source Files with Compile Remove

If a directory contains code that should stay in source control but should not be compiled, remove it from Compile.

xml
1<Project Sdk="Microsoft.NET.Sdk">
2  <PropertyGroup>
3    <TargetFramework>net8.0</TargetFramework>
4  </PropertyGroup>
5
6  <ItemGroup>
7    <Compile Remove="Legacy/**/*.cs" />
8  </ItemGroup>
9</Project>

This is useful for archived code, templates, or generated output that is consumed by tooling rather than by the runtime application.

Exclude Content and None Items Separately

A common surprise is that removing a file from Compile does not stop it from being copied during publish. That happens when the file is a Content item.

xml
1<ItemGroup>
2  <Content Remove="wwwroot/debug-assets/**" />
3  <None Remove="docs/internal/**" />
4</ItemGroup>

Each item type is managed independently. If a file is still showing up, inspect the project evaluation rather than piling on more wildcard rules blindly.

Remove a Folder Broadly and Re-Include Specific Files

When most of a directory should be excluded but a few files should remain, a broad Remove plus a narrow Include is often the cleanest approach.

xml
1<ItemGroup>
2  <Compile Remove="Generated/**/*.cs" />
3  <Compile Include="Generated/PublicApi/Contracts.cs" />
4</ItemGroup>

This is easier to maintain than writing dozens of one-off exclusion lines. It also makes intent obvious to reviewers.

Disable Default Compile Items Only When You Need Full Control

You can turn off automatic source inclusion entirely:

xml
1<PropertyGroup>
2  <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
3</PropertyGroup>
4
5<ItemGroup>
6  <Compile Include="Program.cs" />
7  <Compile Include="Services/**/*.cs" />
8</ItemGroup>

This gives you maximum control, but it also means every new source file must be added on purpose. Most projects do not need that level of manual ownership.

Use Conditions with Caution

Sometimes exclusions should apply only for certain build configurations or target frameworks.

xml
1<ItemGroup Condition="'$(Configuration)' == 'Release'">
2  <Compile Remove="Diagnostics/**/*.cs" />
3</ItemGroup>
4
5<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
6  <Content Remove="Assets/legacy/**" />
7</ItemGroup>

Conditional rules are powerful, but they make the project harder to reason about. If you add them, make sure CI builds all relevant configurations so environment-specific mistakes are caught early.

Verify the Effective Build Inputs

When exclusions do not behave the way you expect, inspect what MSBuild actually evaluated.

bash
dotnet build -v:n

For deeper inspection, generate a binary log:

bash
dotnet build -bl

That log shows which Include, Remove, and conditions produced each item. It is usually the fastest way to find out why a file keeps returning after you thought you excluded it.

Organize the Project to Reduce Exclusion Complexity

Good folder structure makes MSBuild rules simpler. Keep generated artifacts in a dedicated folder such as Generated, store documentation separately from publishable assets, and avoid mixing experimental code with production source when possible.

That way, your project file can use a few clear folder-based rules instead of many fragile file-specific exceptions.

Common Pitfalls

The most common pitfall is removing the wrong item type. A Compile Remove rule does nothing for files that are being included as Content or None.

Another mistake is assuming .gitignore or hiding a file in the IDE changes the build. Those actions affect source control or editor display, not MSBuild evaluation.

Conditional exclusions are also easy to under-test. A project may build locally in Debug and then fail in Release on CI because the exclusion rules differ across configurations.

Summary

  • SDK-style .NET projects include many files automatically, so exclusions must be explicit.
  • Remove files from the correct item type, such as Compile, Content, or None.
  • A broad Remove plus targeted Include entries is often the cleanest pattern.
  • Disable default compile inclusion only if you truly need full manual control.
  • Use build logs to understand MSBuild evaluation instead of guessing.

Course illustration
Course illustration

All Rights Reserved.