.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 Standard - •
net4*(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
*.csprojfilexml<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
bashdotnet list package --outdated dotnet add package <PackageName> --version <LatestVersion>
- •
- •
Migrate
packages.configtoPackageReference:bashdotnet 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:
bash
dotnet build <ProjectName>.csproj
- •Run unit tests:
bash
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