Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Teaches agents to read and safely modify SDK-style .csproj files. Covers project structure, PropertyGroup conventions,
ItemGroup patterns, conditional expressions, Directory.Build.props/.targets, and central package management
(Directory.Packages.props). Each subsection provides annotated XML examples and common modification patterns.
Scope
SDK-style .csproj structure and SDK attribute conventions
PropertyGroup and ItemGroup reading and modification
Conditional expressions and TFM-based conditions
Directory.Build.props/.targets and Central Package Management
Out of scope
Project organization and SDK selection -- see [skill:dotnet-project-structure]
Build error interpretation -- see [skill:dotnet-build-analysis]
Common agent coding mistakes -- see [skill:dotnet-agent-gotchas]
Prerequisites
.NET 8.0+ SDK. SDK-style projects only (legacy .csproj format is not covered). MSBuild (included with .NET SDK).
Cross-references: [skill:dotnet-project-structure] for project organization and SDK selection,
[skill:dotnet-build-analysis] for interpreting build errors from project misconfiguration, [skill:dotnet-agent-gotchas]
for common project structure mistakes agents make.
Subsection 1: SDK-Style Project Structure
SDK-style projects use a <Project Sdk="..."> declaration that imports hundreds of default targets and props.
Understanding what the SDK provides implicitly is essential to avoid redundant or conflicting declarations.
Annotated XML Example
<!-- The Sdk attribute imports default props at the top and targets at the bottom --><!-- This single line replaces dozens of Import statements from legacy .csproj --><ProjectSdk="Microsoft.NET.Sdk"><!--
Common SDK values:
- Microsoft.NET.Sdk -> Console apps, libraries, class libraries
- Microsoft.NET.Sdk.Web -> ASP.NET Core (adds Kestrel, MVC, Razor, shared framework)
- Microsoft.NET.Sdk.Worker -> Background worker services
- Microsoft.NET.Sdk.Razor -> Razor class libraries
- Microsoft.NET.Sdk.BlazorWebAssembly -> Blazor WASM apps
--><!-- SDK-style projects auto-include all *.cs files via default globs --><!-- No need to list individual .cs files in <Compile Include="..."> --><!-- Default globs: **/*.cs for Compile, **/*.resx for EmbeddedResource -->
net9.0
```text
### Common Modification Patterns
**Changing SDK type** -- when an agent creates a web project with the wrong SDK:
```xml
```text
**Disabling default globs** -- rare, but needed when migrating from legacy format or when explicit file control is
required:
```xml
false
false
```text
**Verifying which SDK a project uses:**
```bash
# Check the first line of the .csproj for the Sdk attribute
head -1 src/MyApp/MyApp.csproj
# Output:
```bash
---
## Subsection 2: PropertyGroup Conventions
PropertyGroup elements contain scalar MSBuild properties. The most important properties control the target framework,
language features, and output type.
### Annotated XML Example
```xml
net9.0
enable
enable
Exe
MyApp.Api
MyApp.Api
preview
```text
### Common Modification Patterns
**Enabling nullable for an existing project:**
```xml
enable
```text
**Setting output type for a console app:**
```xml
Exe
```xml
**Adding TreatWarningsAsErrors (recommended for CI parity):**
```xml
true
```text
---
## Subsection 3: ItemGroup Patterns
ItemGroup elements contain collections: package references, project references, file inclusions, and other build items.
Understanding the three main item types prevents common agent mistakes.
### Annotated XML Example
```xml
```text
### Common Modification Patterns
**Adding a NuGet package:**
```bash
# Prefer CLI to avoid formatting issues
dotnet add src/MyApp/MyApp.csproj package Microsoft.EntityFrameworkCore --version 9.0.0
```bash
```xml
```xml
**Adding a project reference:**
```bash
# CLI ensures correct relative path
dotnet add src/MyApp.Api/MyApp.Api.csproj reference src/MyApp.Core/MyApp.Core.csproj
```bash
```xml
```csharp
**Including non-compiled files in output:**
```xml
```json
---
## Subsection 4: Condition Expressions and Multi-Targeting
MSBuild conditions enable TFM-specific properties, platform-specific package references, and build configuration logic.
Understanding condition syntax prevents broken multi-targeting builds.
### Annotated XML Example
```xml
net8.0;net9.0
true
true
```text
### Common Modification Patterns
**Adding a TFM:**
```xml
net8.0
net8.0;net9.0
```text
**Using version-agnostic TFM patterns for platform detection:**
```xml
```text
**Condition syntax reference:**
| Expression | Meaning |
| ------------------------------ | ------------------------------ |
| `'$(Prop)' == 'value'` | Exact match (case-insensitive) |
| `'$(Prop)' != 'value'` | Not equal |
| `$(Prop.StartsWith('prefix'))` | String starts with |
| `$(Prop.Contains('sub'))` | String contains |
| `'$(Prop)' == ''` | Property is empty/not set |
| `Exists('path')` | File or directory exists |
---
## Subsection 5: Directory.Build.props and Directory.Build.targets
These files centralize shared build configuration. MSBuild automatically imports `Directory.Build.props` (before the
project) and `Directory.Build.targets` (after the project) from the current directory and all parent directories up to
the filesystem root.
### Annotated XML: Directory.Build.props
```xml
net9.0
enable
enable
true
true
true
MyCompany
MyCompany
MIT
```text
### Annotated XML: Directory.Build.targets
```xml
```text
### Common Modification Patterns
**Hierarchy and override behavior:**
```text
repo-root/
Directory.Build.props <-- applies to ALL projects
src/
Directory.Build.props <-- applies to src/ projects only
MyApp.Api/
MyApp.Api.csproj <-- inherits from src/ props (NOT repo-root/)
```csharp
MSBuild imports the nearest `Directory.Build.props` found walking upward. If a nested `Directory.Build.props` exists, it
shadows the parent. To chain both, the nested file must explicitly import the parent:
```xml
MyApp.$(MSBuildProjectName)
```text
**When to use .props vs .targets:**
| Use .props for | Use .targets for |
| --------------------------------------- | -------------------------------------------------- |
| Property defaults (TFM, nullable, etc.) | Items that depend on project properties |
| Package metadata (authors, license) | Custom build targets (AfterTargets, BeforeTargets) |
| Properties projects can override | Analyzer packages added to all projects |
---
## Subsection 6: Directory.Packages.props (Central Package Management)
Central Package Management (CPM) centralizes NuGet package versions in a single `Directory.Packages.props` file.
Individual projects reference packages without specifying versions.
### Annotated XML Example
```xml
true
```text
**Project file with CPM enabled:**
```xml
net9.0
```text
### Common Modification Patterns
**Enabling CPM in an existing solution:**
1. Create `Directory.Packages.props` at the solution root with
`true`.
2. Move all `Version` attributes from `PackageReference` items into `PackageVersion` entries in the central file.
3. Remove `Version` from all `PackageReference` items in individual `.csproj` files.
```bash
# Find all PackageReference entries with Version attributes
grep -rn 'PackageReference Include=.*Version=' --include="*.csproj" src/
```bash
**Overriding a version in a specific project** (escape hatch):
```xml
```csharp
**Hierarchical resolution:** `Directory.Packages.props` resolves upward from the project directory, the same as
`Directory.Build.props`. In monorepos, place the central file at the repo root. Sub-directories can have their own
`Directory.Packages.props` -- the nearest one wins.
**Migrating from per-project versions:**
```bash
# List all unique packages and versions across the solution
dotnet list src/MyApp.sln package --format json
# Use this output to build the central PackageVersion list
```bash
---
## Slopwatch Anti-Patterns
These patterns in project files indicate an agent is hiding problems rather than fixing them. See
[skill:dotnet-slopwatch] for the automated quality gate that detects these patterns.
### NoWarn in .csproj
```xml
CS8600;CS8602;CS8604;IL2026;IL2046;IL3050
```text
`` in the project file suppresses warnings for the entire project, making issues invisible. This is worse than
`#pragma` because it has no scope boundary and cannot be audited per-file.
**Fix:** Remove `` entries and fix the underlying issues. For warnings that genuinely do not apply project-wide,
configure severity in `.editorconfig` instead:
```ini
# .editorconfig -- preferred over for controlled suppression
[*.cs]
dotnet_diagnostic.CA2007.severity = none # No SynchronizationContext in ASP.NET Core
```csharp
### Suppressed Analyzers in Directory.Build.props
```xml
$(NoWarn);CA1062;CA1822;CA2007
false
false
```text
Disabling analyzers in `Directory.Build.props` silences them across every project in the solution, including new
projects added later. Agents sometimes do this to achieve a clean build quickly.
**Fix:** Keep analyzers enabled globally. Address warnings per-project or per-file. If a specific rule category does not
apply (e.g., CA2007 in ASP.NET Core apps), suppress it in `.editorconfig` at the appropriate scope with a comment
explaining why.
---
## Cross-References
- [skill:dotnet-project-structure] -- SDK selection, project organization, solution layout
- [skill:dotnet-build-analysis] -- interpreting build errors caused by project misconfiguration
- [skill:dotnet-agent-gotchas] -- common project structure mistakes agents make (wrong SDK, broken refs)
## Code Navigation (Serena MCP)
**Primary approach:** Use Serena symbol operations for efficient code navigation:
1. **Find definitions**: `serena_find_symbol` instead of text search
2. **Understand structure**: `serena_get_symbols_overview` for file organization
3. **Track references**: `serena_find_referencing_symbols` for impact analysis
4. **Precise edits**: `serena_replace_symbol_body` for clean modifications
**When to use Serena vs traditional tools:**
- ✅ **Use Serena**: Navigation, refactoring, dependency analysis, precise edits
- ✅ **Use Read/Grep**: Reading full files, pattern matching, simple text operations
- ✅ **Fallback**: If Serena unavailable, traditional tools work fine
**Example workflow:**
```text
# Instead of:
Read: src/Services/OrderService.cs
Grep: "public void ProcessOrder"
# Use:
serena_find_symbol: "OrderService/ProcessOrder"
serena_get_symbols_overview: "src/Services/OrderService.cs"
```
## References
- [MSBuild Project SDK](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview)
- [MSBuild Reference](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild)
- [Central Package Management](https://learn.microsoft.com/en-us/nuget/consume-packages/Central-Package-Management)
- [Directory.Build.props/targets](https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-by-directory)
- [MSBuild Conditions](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-conditions)
- [SDK-style Project Format](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview)
<PropertyGroup>
<TargetFramework>
</TargetFramework>
</PropertyGroup>
</Project>
<!-- WRONG: console SDK for a web project -->
<ProjectSdk="Microsoft.NET.Sdk">
<!-- CORRECT: Web SDK includes ASP.NET Core shared framework -->
<ProjectSdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Disable automatic inclusion of *.cs files -->
<EnableDefaultCompileItems>
</EnableDefaultCompileItems>
<!-- Disable all default items (Compile, EmbeddedResource, Content) -->
<EnableDefaultItems>
</EnableDefaultItems>
</PropertyGroup>
<ProjectSdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Target Framework Moniker (TFM) -- determines runtime and API surface -->
<!-- Use the latest LTS or STS release; prefer the repo's existing TFM. -->
<TargetFramework>
</TargetFramework>
<!-- For multi-targeting, use plural form (see Subsection 4) -->