.NET Project Upgrade Standards
Core Requirements
- MUST iterate and keep going until the problem is solved
- MUST upgrade projects sequentially, not all at once
- MUST ensure each project builds and passes tests before proceeding
- MUST update CI/CD files only after successful completion of all builds
- MUST work on specified branch or create
upgrade-net-frameworkif none specified
Preparation
1. Identify Project Type
Inspect each *.csproj:
netcoreapp*→ .NET Core / .NET (modern)netstandard*→ .NET Standardnet4*(e.g., net472) → .NET Framework
2. Select Target Version
- .NET (Core/Modern): Upgrade to the latest LTS (e.g.,
net8.0) - .NET Standard: Prefer migrating to .NET 6+ if possible; if staying, target
netstandard2.1 - .NET Framework: Upgrade to at least 4.8, or migrate to .NET 6+ if feasible
3. Review Release Notes
Upgrade Strategy
- Start with independent class library projects (least dependencies)
- Gradually move to projects with higher dependencies (e.g., APIs, Azure Functions)
- Ensure each project builds and passes tests before proceeding
- Update CI/CD files only after all successful builds
Determine Upgrade Sequence
To identify dependencies:
Visual Studio: Check Dependencies in Solution Explorer
dotnet CLI:
dotnet list <ProjectName>.csproj reference
Dependency Graph Generator:
dotnet msbuild <SolutionName>.sln /t:GenerateRestoreGraphFile /p:RestoreGraphOutputPath=graph.json
Analyze Each Project
For each project:
-
Open the
*.csprojfile<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> </ItemGroup> </Project> -
Check for:
TargetFramework→ Change to desired version (e.g.,net8.0)PackageReference→ Verify NuGet package compatibility
dotnet list package --outdated dotnet add package <PackageName> --version <LatestVersion> -
Migrate
packages.configtoPackageReference:dotnet migrate <ProjectPath>
Code Adjustments
Review code for required changes after upgrading packages.
Common Migration Examples
System.Text.Json vs Newtonsoft.Json:
// Old (Newtonsoft.Json)
var obj = JsonConvert.DeserializeObject<MyClass>(jsonString);
// New (System.Text.Json)
var obj = JsonSerializer.Deserialize<MyClass>(jsonString);
IHostBuilder vs WebHostBuilder:
// Old
IWebHostBuilder builder = new WebHostBuilder();
// New
IHostBuilder builder = Host.CreateDefaultBuilder(args);
Azure SDK Updates:
// Old (Blob storage SDK v11)
CloudBlobClient client = storageAccount.CreateCloudBlobClient();
// New (Azure.Storage.Blobs)
BlobServiceClient client = new BlobServiceClient(connectionString);
Upgrade Process Per Project
- Update
TargetFrameworkin.csproj - Update NuGet packages to compatible versions
- After restoring latest DLLs, review code for required changes
- Rebuild the project:
dotnet build <ProjectName>.csproj - Run unit tests:
dotnet test - Fix build or runtime issues before proceeding
Handling Breaking Changes
- Review .NET Upgrade Assistant suggestions
- Common issues:
- Deprecated APIs → Replace with supported alternatives
- Package incompatibility → Find updated NuGet or migrate to Microsoft-supported library
- Configuration differences (e.g.,
Startup.cs→Program.csin .NET 6+)
Validate End-to-End
After all projects are upgraded:
- Rebuild entire solution
- Run all automated tests (unit, integration)
- Deploy to lower environment (UAT/Dev) for verification
- Validate:
- APIs start without runtime errors
- Logging and monitoring integrations work
- Dependencies (databases, queues, caches) connect as expected
Tools & Automation
.NET Upgrade Assistant (Optional):
dotnet tool install -g upgrade-assistant
upgrade-assistant upgrade <SolutionName>.sln
Update CI/CD Pipelines
When upgrading .NET projects, build pipelines must reference correct SDK, NuGet versions, and tasks.
Pipeline Update Steps
a. Locate pipeline YAML files:
.azuredevops/.pipelines/Deployment/- Root of repo (
*.yml)
b. Scan for .NET SDK installation tasks:
- task: UseDotNet@2
inputs:
version: <current-sdk-version>
c. Update SDK version:
- task: UseDotNet@2
displayName: Use .NET SDK <new-version>
inputs:
version: <new-version>
includePreviewVersions: true # optional for preview releases
d. Update NuGet Tool version:
- task: NuGetToolInstaller@0
displayName: Use NuGet <new-version>
inputs:
versionSpec: <new-version>
checkLatest: true
e. Validate the pipeline:
- Commit changes to feature branch
- Trigger CI build to confirm:
- YAML is valid
- SDK installs successfully
- Projects restore, build, and test with upgraded framework
Commit Plan
- Always work on specified branch or create
upgrade-net-framework - Commit after each successful project upgrade
- If a project fails, rollback to previous commit and fix incrementally
Upgrade Checklist (Per Project)
Track progress using this table in the Pull Request:
| Project Name | Target Framework | Dependencies Updated | Builds Successfully | Tests Passing | Deployment Verified | Notes |
|---|---|---|---|---|---|---|
| Project A | ☐ net8.0 | ☐ | ☐ | ☐ | ☐ | |
| Project B | ☐ net8.0 | ☐ | ☐ | ☐ | ☐ | |
| Project C | ☐ net8.0 | ☐ | ☐ | ☐ | ☐ |
Commit & PR Guidelines
- Use single PR per repository:
- Title:
Upgrade to .NET [VERSION] - Include:
- Updated target frameworks
- NuGet upgrade summary
- Test results summary
- Title:
- Tag with
breaking-changeif APIs were replaced
Multi-Repo Execution
For organizations with multiple repositories:
- Store upgrade guidelines in central template repo
- Detect project type per repo
- Apply appropriate upgrade path
- Open PRs for each repo
Best Practices
- MUST prefer migration to Modern .NET (.NET 6/8) for long-term support
- MUST automate tests early - CI/CD should block merges if tests fail
- SHOULD perform incremental upgrades for large solutions (one project at a time)
- MUST ensure thorough but concise thinking process
- MUST avoid unnecessary repetition and verbosity
