Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 167 additions & 2 deletions docs/core/install/upgrade.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
title: Upgrade to a new .NET version
description: Learn how to upgrade an app to a new .NET version. Upgrade .NET when the current version goes out of support or when you want to use new features of .NET.
ms.date: 11/11/2024
description: Learn how to upgrade an app to a new .NET version. Upgrade .NET when the current version goes out of support or when you want to use new features of .NET. Control versions of SDK, analyzers, and packages for predictable builds.
ms.date: 10/28/2025
ai-usage: ai-assisted
---

# Upgrade to a new .NET version
Expand Down Expand Up @@ -51,6 +52,165 @@ More resources:
- [Migrate an ASP.NET Core app](/aspnet/core/migration/)
- [Upgrade .NET MAUI from .NET 7 to .NET 8](https://github.com/dotnet/maui/wiki/Upgrading-.NET-MAUI-from-.NET-7-to-.NET-8)

## Version pinning

When you upgrade development tools like the .NET SDK, Visual Studio, or other components, you might encounter new behaviors, analyzer warnings, or breaking changes that affect your build process. By pinning to a version, you can upgrade your development environment while maintaining control over when specific components are updated in your projects.

Version pinning provides several benefits:

- **Predictable builds**: Ensures consistent build results across different machines and CI/CD environments.
- **Gradual adoption**: Allows you to adopt new features incrementally rather than all at once.
- **Avoid unexpected changes**: Prevents new analyzer rules, SDK behaviors, or package versions from causing build failures.
- **Team coordination**: Enables teams to upgrade together at a planned time rather than individually when tools update.
- **Debugging and troubleshooting**: Makes it easier to isolate issues when you control which versions changed.

The following sections describe various mechanisms for controlling versions of different components in your .NET projects:

- [Control SDK version with global.json](#control-sdk-version-with-globaljson)
- [Control analyzer behavior](#control-analyzer-behavior)
- [Control NuGet package versions](#control-nuget-package-versions)
- [Control MSBuild version](#control-msbuild-version)

### Control SDK version with global.json

You can pin the .NET SDK version for a project or solution by using a *global.json* file. This file specifies which SDK version to use when running .NET CLI commands and is independent of the runtime version your project targets.

Create a *global.json* file in your solution root directory:

```dotnetcli
dotnet new globaljson --sdk-version 9.0.100 --roll-forward latestFeature
```

This command creates the following *global.json* file that pins the SDK to version 9.0.100 or any later patch or feature band within the 9.0 major version:

```json
{
"sdk": {
"version": "9.0.100",
"rollForward": "latestFeature"
}
}
```

The `rollForward` policy controls how the SDK version is selected when the exact version isn't available. This configuration ensures that when you upgrade Visual Studio or install a new SDK, your project continues to use SDK 9.0.x until you explicitly update the *global.json* file.

For more information, see [global.json overview](../tools/global-json.md).

### Control analyzer behavior

Code analyzers can introduce new warnings or change behavior between versions. You can control analyzer versions to maintain consistent builds by using the [`AnalysisLevel` property](../project-sdk/msbuild-props.md#analysislevel). This property allows you to lock to a specific version of analyzer rules, preventing new rules from being introduced when you upgrade the SDK.

```xml
<PropertyGroup>
<AnalysisLevel>9.0</AnalysisLevel>
</PropertyGroup>
```

When set to `9.0`, only the analyzer rules that shipped with .NET 9 are enabled, even if you're using the .NET 10 SDK. This prevents new .NET 10 analyzer rules from affecting your build until you're ready to address them.

For more information, see [AnalysisLevel](../project-sdk/msbuild-props.md#analysislevel).

### Control NuGet package versions

By managing package versions consistently across projects, you can prevent unexpected updates and maintain reliable builds.

- [Package lock files](#package-lock-files)
- [Central package management](#central-package-management)
- [Package source mapping](#package-source-mapping)

#### Package lock files

Package lock files ensure that package restore operations use the exact same package versions across different environments. The lock file (`packages.lock.json`) records the exact versions of all packages and their dependencies.

Enable lock files in your project file:

```xml
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
```

To ensure builds fail if the lock file is out of date:

```xml
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<RestoreLockedMode>true</RestoreLockedMode>
</PropertyGroup>
```

After enabling lock files, run `dotnet restore` to generate the *packages.lock.json* file. Commit this file to source control.

#### Central package management

Central package management (CPM) allows you to manage package versions in a single location for all projects in a solution. This approach simplifies version management and ensures consistency across projects.

Create a *Directory.Packages.props* file in your solution root:

```xml
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>

<ItemGroup>
<PackageVersion Include="Azure.Identity" Version="1.17.0" />
<PackageVersion Include="Microsoft.Extensions.AI" Version="9.10.1" />
</ItemGroup>
</Project>
```

In your project files, reference packages without specifying a version:

```xml
<ItemGroup>
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Extensions.AI" />
</ItemGroup>
```

#### Package source mapping

Package source mapping allows you to control which NuGet feeds are used for specific packages, improving security and reliability.

Configure source mapping in your *nuget.config* file:

```xml
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="contoso" value="https://contoso.com/packages/" />
</packageSources>

<packageSourceMapping>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="contoso">
<package pattern="Contoso.*" />
</packageSource>
</packageSourceMapping>
</configuration>
```

This configuration ensures that all packages starting with `Contoso.` are only restored from the `contoso` feed, while other packages come from `nuget.org`.

For more information, see [NuGet package restore](../tools/dotnet-restore.md).

### Control MSBuild version

Visual Studio supports side-by-side installation of multiple versions. For example, you can install Visual Studio 2026 and Visual Studio 2022 on the same machine. Each Visual Studio version includes a corresponding .NET SDK. When you update Visual Studio, the included SDK version is updated as well. However, you can continue using older SDK versions by installing them separately from the [.NET download page](https://dotnet.microsoft.com/download).

MSBuild versions correspond to Visual Studio versions. For example, Visual Studio 2022 version 17.8 includes MSBuild 17.8. The .NET SDK also includes MSBuild. When you use `dotnet build`, you're using the MSBuild version included with the SDK specified by *global.json* or the latest installed SDK.

To use a specific MSBuild version:

- Use `dotnet build` with a pinned SDK version in *global.json*.
- Launch the appropriate Visual Studio Developer Command Prompt, which sets up the environment for that Visual Studio version's MSBuild.
- Directly invoke MSBuild from a specific Visual Studio installation (for example, `"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\MSBuild.exe"`).

For more information, see [.NET SDK, MSBuild, and Visual Studio versioning](../porting/versioning-sdk-msbuild-vs.md).

## Update continuous integration (CI)

CI pipelines follow a similar update process as project files and Dockerfiles. Typically, you can update [CI pipelines](https://github.com/actions/setup-dotnet) by changing only version values.
Expand All @@ -68,3 +228,8 @@ FROM mcr.microsoft.com/dotnet/aspnet:9.0
```

In a cloud service like [Azure App Service](/azure/app-service/quickstart-dotnetcore), a configuration change is needed.

## See also

- [Breaking changes in .NET 10](../compatibility/10.0.md)
- [Migrate an ASP.NET Core app](/aspnet/core/migration/)
16 changes: 8 additions & 8 deletions docs/fundamentals/code-analysis/configuration-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ Rule-specific options can be applied to a single rule, a set of rules, or all ru

The following table shows the different rule severities that you can configure for all analyzer rules, including [code quality](quality-rules/index.md) and [code style](style-rules/index.md) rules.

| Severity configuration value | Build-time behavior |
|-|-|
| `error` | Violations appear as build *errors* and cause builds to fail.|
| `warning` | Violations appear as build *warnings* but do not cause builds to fail (unless you have an option set to treat warnings as errors). |
| `suggestion` | Violations appear as build *messages* and as suggestions in the Visual Studio IDE. (In Visual Studio, suggestions appear as three gray dots under the first two characters.) |
| `silent` | Violations aren't visible to the user.<br/><br/>However, for code-style rules, Visual Studio code-generation features still generate code in this style. These rules also participate in cleanup and appear in the **Quick Actions and Refactorings** menu in Visual Studio. |
| `none` | Rule is suppressed completely.<br/><br/>However, for code-style rules, Visual Studio code-generation features still generate code in this style. |
| `default` | The default severity of the rule is used. The default severities for each .NET release are listed in the [roslyn-analyzers repo](https://github.com/dotnet/roslyn-analyzers/blob/main/src/NetAnalyzers/Core/AnalyzerReleases.Shipped.md). In that table, "Disabled" corresponds to `none`, "Hidden" corresponds to `silent`, and "Info" corresponds to `suggestion`. |
| Severity configuration value | Build-time behavior |
|------------------------------|---------------------------------------------------------------|
| `error` | Violations appear as build *errors* and cause builds to fail. |
| `warning` | Violations appear as build *warnings* but do not cause builds to fail (unless you have an option set to treat warnings as errors). |
| `suggestion` | Violations appear as build *messages* and as suggestions in the Visual Studio IDE. (In Visual Studio, suggestions appear as three gray dots under the first two characters.) |
| `silent` | Violations aren't visible to the user.<br/><br/>However, for code-style rules, Visual Studio code-generation features still generate code in this style. These rules also participate in cleanup and appear in the **Quick Actions and Refactorings** menu in Visual Studio. |
| `none` | Rule is suppressed completely.<br/><br/>However, for code-style rules, Visual Studio code-generation features still generate code in this style. |
| `default` | The default severity of the rule is used. The default severities for each .NET release are listed in the [roslyn-analyzers repo](https://github.com/dotnet/roslyn-analyzers/blob/main/src/NetAnalyzers/Core/AnalyzerReleases.Shipped.md). In that table, "Disabled" corresponds to `none`, "Hidden" corresponds to `silent`, and "Info" corresponds to `suggestion`. |

#### Scope

Expand Down