.NET 6 Upgrade - Part 2 - .NET Upgrade Assistant

2022, Nov 25

Upgrading from .NET Framework to .NET 6 is possible via assistants, in this article we are exploring the .NET Upgrade Assistant provided by Microsoft. This is part 2 of 2 in this series.

The assistant

Microsoft provides a command-line tool1 to assess .NET Framework apps. It provides an analysis report for each of the projects in the solution containing details on:

  • Package dependencies that need to be removed/added/upgraded.
  • References that need to be removed/added/upgraded.
  • Framework References that need to be removed/added/upgraded.
  • Call out if there is a package upgrade across major versions that could lead towards breaking changes.
  • Unsupported API used in the projects with pointers to a recommended path forward if one is available.

Similarly to the Porting Assistant, the tool is not going to do magical things but will help you to identify critical points in the solution that need to be reviewed.

Supported project types and languages

It is worth mentioning that the tool supports the following project types:

  • ASP.NET MVC
  • Windows Forms
  • Windows Presentation Foundation (WPF)
  • Console app
  • Libraries
  • UWP to Windows App SDK (WinUI)
  • Xamarin.Forms to .NET MAUI

The tool supports C# and Visual Basic projects.

An example

Do you remember ASP.NET MVC? The sample available https://github.com/aspnet/samples/tree/main/samples/aspnet/MVC/EnumSample.

Interestingly enough this solution works on .NET Framework 4.5, but I didn't dare to install it on my current machine, so I manually tweaked the Project file to .NET Framework 4.8.

I recommend a separate machine, probably a VM to run this sort of exercise.

If you are in Visual Studio 2022 you get this warning.

Not supported

As you do the framework change, it modifies the project Target Framework:

<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>

Solution

If you run the Enum project, it will work:

Running the mvc

The nitty-gritty

There are some prerequisites before installing the Upgrade tool. Make sure you install the upgrade assistant:

dotnet tool install -g --add-source "https://api.nuget.org/v3/index.json" --ignore-failed-sources upgrade-assistant

Assessment

Run the analyzer to verify the solution on .NET 6:

upgrade-assistant analyze --target-tfm-support LTS <Path to csproj or sln to upgrade>

Analysis-1 Analysis-2

From here we can see there will be some hiccups.

Full usage information:

Usage:
  upgrade-assistant analyze [options] <project>

Arguments:
  <project>

Options:
  --extension <extension>                        Specifies a .NET Upgrade Assistant extension package to include. This
                                                 could be an ExtensionManifest.json file, a directory containing an
                                                 ExtensionManifest.json file, or a zip archive containing an extension.
                                                 This option can be specified multiple times.
  -v, --verbose                                  Enable verbose diagnostics
  --target-tfm-support <Current|LTS|Preview>     Select if you would like the Long Term Support (LTS), Current, or
                                                 Preview TFM. See
                                                 https://dotnet.microsoft.com/platform/support/policy/dotnet-core for
                                                 details for what these mean.
  --format  <HTML>                               Specify the format in which the analysis report will be generated. Currently supports html other than the default SARIF format.
  --version                                      Show version information
  -?, -h, --help                                 Show help and usage information

I have both .NET 6 and .NET 7 available in my machine, but I enforced .NET 6 LTS to be used with --target-tfm-support

The default output produced will be a file of type .SARIF format, which can be opened on VStudio Code via extension:

SARIF

SARIF_EXTENSION

Upgrading

Run the analyzer to upgrade the solution on .NET 6:

upgrade-assistant upgrade --target-tfm-support LTS --non-interactive <Path to csproj or sln to upgrade>

If you want an automated way of upgrading all the projects, make sure to set --non-interactive when running the tool.

The output is verbose:

upgrade-1 upgrade-2 upgrade-3 upgrade-4 upgrade-5 upgrade-6

Full usage information:

Usage:
  upgrade-assistant upgrade <project> [command] [options]

Arguments:
  <project>  The path to a project or solution file to be used.

Options:
  -x, --extension <extension>                    Specifies a .NET Upgrade Assistant extension package to include. This could be an ExtensionManifest.json file, a directory
                                                 containing an ExtensionManifest.json file, or a zip archive containing an extension. This option can be specified multiple
                                                 times.
  -o, --option <option>                          Specifies an option that should be added to Upgrade Assistant that may be used by extensions.
  -e, --entry-point <entry-point>                Provides the entry-point project to start the upgrade process. This may include globbing patterns such as '*' for match.
  -i, --ignore-unsupported-features              Acknowledges that upgrade-assistant will not be able to completely upgrade a project. This indicates that the solution must
                                                 be redesigned (e.g. consider Blazor to replace Web Forms).
  --vs-path <vs-path>                            Path to a VS install directory to be used for %VSINSTALLDIR%. If not provided, the latest installed version will be used.
  --msbuild-path <msbuild-path>                  Path to a MSBuild install directory to be used. If not provided, the latest installed version will be used.
  -t, --target-tfm-support <LTS|Preview|STS>     Select if you would like the Long Term Support (LTS), Standard Term Support (STS), or Preview TFM. See
                                                 https://dotnet.microsoft.com/platform/support/policy/dotnet-core for details on what these mean.
  -v, --verbose                                  Enable verbose diagnostics
  -f, --format <format>                          Specify format of analyze result. If not provided, a sarif file will be produced. Available default values: "sarif", "html"
  --skip-backup                                  Disables backing up the project. This is not recommended unless the project is in source control since this tool will make
                                                 large changes to both the project and source files.
  --non-interactive                              Automatically select each first option in non-interactive mode.
  --non-interactive-wait <non-interactive-wait>  Wait the supplied seconds before moving on to the next option in non-interactive mode.
  -?, -h, --help                                 Show help and usage information


Commands:
  list-formats

The same .SARIF report is created at the end of processing on a file called UpgradeReport.sarif.

The new upgraded solution

So the solution was migrated from .NET Framework 4.8 to .NET 6, but will it work?

Similar to the previous article, the solution will not even compile. This will give you an idea of the efforts required, so you can provide estimates, and get the team to work on it.

A lot is going on in this MVC project, as you can see in the csproj below. A good approach in this case would be to start a new project and move files across.

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
    <RestorePackages>true</RestorePackages>
  </PropertyGroup>
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <OutputPath>bin\</OutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Compile Update="Global.asax.cs">
      <DependentUpon>Global.asax</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <None Include="Web.Debug.config">
      <DependentUpon>Web.config</DependentUpon>
    </None>
    <None Include="Web.Release.config">
      <DependentUpon>Web.config</DependentUpon>
    </None>
  </ItemGroup>
  <ItemGroup>
    <Folder Include="App_Data\" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="bootstrap" Version="3.2.0" />
    <PackageReference Include="jQuery" Version="2.1.1" />
    <PackageReference Include="jQuery.Validation" Version="1.13.0" />
    <PackageReference Include="Microsoft.jQuery.Unobtrusive.Validation" Version="3.2.3" />
    <PackageReference Include="Modernizr" Version="2.8.3" />
    <PackageReference Include="Respond" Version="1.4.2" />
    <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
    <PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
    <PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" />
    <PackageReference Include="Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers" Version="0.4.355802">
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="EntityFramework" Version="6.4.4" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.11" />
  </ItemGroup>
</Project>

My Opinion

This is a great tool, that will help to point out the issues ahead of time during upgrades.

I tried using the HTML format when generating the report output, but the HTML is too simple and it doesn't allow interactions, but the .SARIF extension on VStudio Code works much better, as you can drill down to the issues dynamically.

If I was to upgrade a single project, rather than do it non-interactively, I would go one step at a time as the tool asks for you to take decisions. This is much more verbose, but it gives you a better understanding of what the tool is trying to do.

Full Series

.NET 6 Upgrade - Part 1 - Port Assistant

.NET 6 Upgrade - Part 2 - .NET Upgrade Assistant


  1. Upgrade Assistant Upgrade Assistant