Upgrading your .NET projects with Visual Studio
Now you can upgrade any .NET application to the latest version of .NET inside of Visual Studio! We are happy to introduce it as a Visual Studio extension and will upgrade your .NET Framework or .NET Core web- and desktop apps. Some project types are in development and coming soon, see the details below.
Why upgrade and to what version?
If your applications are built for .NET Framework or .NET Core, now is a great time to upgrade them to .NET 6 (Long Term Support version) or .NET 7 (Standard Term Support version) that have much better performance and give you access to the latest features and capabilities. There have been huge improvements between .NET Framework and the latest .NET, but even if you’re targeting .NET Core 3.1 or earlier, it has reached the end of support in December 2022.
We recommend to port to .NET 6 or .NET 7!
Between those two, .NET 6 has longer support time and .NET 7 is the latest, so has newer features. We release a new version of .NET every year in November and every even version number is supported for 3 years (Long Term Support, or LTS for short). So, you can either stay on the latest cutting-edge tech and upgrade every year, or switch from LTS to LTS once every 2-3 years.
About Upgrade Assistant
Upgrading your application, especially from .NET Framework, was a complicated process. We kept prototyping and improving in this area to simplify your upgrades. In the past, you might have used the Upgrade Assistant CLI tool or Microsoft Project Migrations. We have collected your feedback, big thanks to everyone who filled in our survey or left us comments, created issues and feature requests! To address your feedback, we concluded that we needed to provide a unified upgrade experience for every project type inside of Visual Studio.
Now you will be able to upgrade every type of .NET application from any initial version (.NET Framework or .NET Core) by right-clicking on your project in Solution Explorer and choose “Upgrade”. Don’t forget to install the extension first.
The general philosophy of Upgrade Assistant is that it will take care of the mechanics, but depending on what framework and project type you’re upgrading from, you should expect to do some manual post processing. While we try to automatically fix breaking changes, it cannot detect and fix all of them. So you might need to make some additional modifications to get the code to compile and you need to test thoroughly to ensure your code continues to work as expected.
Supported application types
We have a goal to support every .NET project type. Also, we think of this tool not just as a one-time upgrade from .NET Framework to .NET 6/7, but as the way to upgrade your application to the latest .NET in the future as well. Besides changing the target framework version, the tool will be able to modify your code to fix breaking changes. These are our plans for the future, and currently here is what the tool supports in the latest version:
- Class libraries
These workloads are at parity with Upgrade Assistant CLI tool.
- Xamarin to .NET MAUI migration
- UWP to WinUI migration
- WCF to WCF Core migration
Those migration types are in development, and you already can upgrade these projects, but we don’t have the code fixers for these projects yet. If you need to migrate these project types today, we recommend using the existing Upgrade Assistant command line tool, which already has code fixers. The Visual Studio extension will get them soon too.
Different upgrade types
Upgrade assistant supports 3 upgrade types. Different types are recommended for different project types, so you will see only those options that would work well for your app.
- In-place. In this case your original project will be upgraded all at once. If you are using source control and prefer to manage the copies yourself, for example, by using branches, this option is for you.
- Side-by-side. With this option your original project will be untouched, and a copy of it will be added to the solution which will contain the upgraded code. This type can be handy if your application has many dependencies that might be broken after the upgrade. This way you can check-in your progress and not worry about the application not building.
- Side-by-side incremental. This is the ideal choice for web applications. Upgrade from ASP.NET to ASP.NET Core requires a lot of work and at times manual refactoring (because these two technologies are very different). Class Libraries are often used together with web apps, so we enable this type of upgrade for Class Libraries as well. Incremental upgrade will put a .NET 6/7 project next to your existing .NET Framework project and route endpoints that are implemented in the .NET 6/7 project there, while all other calls will be sent to .NET Framework application. This way you can combine upgrade with feature development and move your items to .NET 6/7 one by one without breaking your app. This approach was originally built in Microsoft Project Migrations tool, you can think of Upgrade Assistant in Visual Studio as a new improved and extended version of Microsoft Project Migrations. Upgrading from .NET Core or .NET 5 to .NET 6/7 is much easier than from .NET Framework, so for those cases In-place option is recommended.
In the table below you can find the status of all upgrade types by project type.
|ASP.NET from .NET Framework||N/A||N/A||supported|
|ASP.NET from .NET Core, .NET5+||supported||N/A||N/A|
|WinForms from .NET Framework||supported||supported||N/A|
|WinForms from .NET Core, .NET5+||supported||N/A||N/A|
|WPF from .NET Framework||supported||supported||N/A|
|WPF from .NET Core, .NET5+||supported||N/A||N/A|
|Class Library from .NET Framework||supported||supported||supported|
|Class Library from .NET Core, .NET5+||supported||N/A||N/A|
|Console from .NET Framework||supported||supported||N/A|
|Console from .NET Core, .NET5+||supported||N/A||N/A|
|Xamarin to MAUI||in development||in development||N/A|
|MAUI from older versions||in development||N/A||N/A|
|UWP to WinUI||in development||in development||N/A|
|WinUI from older versions||in development||N/A||N/A|
|Azure Functions||in development||N/A||N/A|
|WCF to WCF Core||in development||N/A||N/A|
Step by step upgrade
- Install Upgrade Assistant Visual Studio extension.
- In Visual Studio in Solution Explorer right-click on the project you want to upgrade, choose Upgrade.
- You will see the main page with a few options for your upgrade.Which option to choose is described in different upgrade types.
- For this example, I choose In-place. Side-by-side would be very similar with a few extra steps. Additional features of side-by-side incremental are described in our previous blog post.
- Then you need to choose the framework you want to upgrade to. The tool will suggest only options that make sense for your project type. In my example, it’s a .NET Framework class library so it also suggests .NET Standard.All upgrades are forward, meaning that if your project for example is already on .NET 6, only .NET 7 and later will be offered. If you do not have the chosen SDK installed on your computer, you’ll be prompted to install it on the next step. Simply follow the link and go back to your upgrade after the SDK is installed. .NET Standard is suggested only for Class Libraries that were targeting .NET Framework.
- Now is time to choose the components you’d like to upgrade. Eventually you will need to upgrade everything, but if you prefer doing it step-by-step, this is the screen to select what do you want to start with.
- After you click Upgrade selection you will see the progress of your upgrade and a report after it is completed.
You can now upgrade your .NET projects right from inside Visual Studio. Please tell us how this works for you and what else you’d need for your projects by filling out this brief survey.
You can also file issues or feature requests from Visual Studio by choosing Help | Send Feedback. Ensure to mention “Upgrade Assistant vsix” in the title.
- .NET Upgrade Assistant – Visual Studio Marketplace
- dotnet/systemweb-adapters (github.com)
- YARP Documentation (microsoft.github.io)
- Incremental ASP.NET to ASP.NET Core Migration – .NET Blog (microsoft.com)
- Incremental ASP.NET Migration Tooling Preview 2 – .NET Blog (microsoft.com)
- Migrating from ASP.NET to ASP.NET Core in Visual Studio
- Migrating from ASP.NET to ASP.NET Core (Part 4)
- Migrating from ASP.NET to ASP.NET Core with Project Migrations Part 5
Why the contradiction?
Now you can upgrade any .NET application to the latest version of .NET inside of Visual Studio! …. Some project types are in development and coming soon, see the details below.
My read was that the Visual Studio extension is now enabled for all application types. Previously, the tooling was restricted to web projects. The later text qualifies what is delivered today vs what will come later.
Yes to Immo, Upgrade Assistant already supports all mentioned project types and can do basic upgrade steps. For types mentioned in “coming soon”, more work is in progress to address changes needed for those particular project types, so more functionality will come soon.
But yes, good point, thank you 🙂
“depending on what framework and project type you’re upgrading from, you should expect to do some manual post processing. While we try to automatically fix breaking changes, it cannot detect and fix all of them. So you might need to make some additional modifications …”
“Besides changing the target framework version, the tool will be able to modify your code to fix breaking changes.”
but, congratulations on this … if it actually works.
I don’t believe this is inconsistent. You can refer to the underlying CLI tool on Github that backs this extension for more information but it automates the boilerplate conversion stuff. This is done using “extensions” that can be added (and you can define your own). There are extensions for some common stuff. For example it can take an
app.configand generate an equivalent
appsettings.json. It also knows how to convert an MVC controller to a .NET 6 controller. So that is what is meant by it will modify your code.
But there is so many things it cannot possible convert that there is pretty much always a manual process after. For example if you’re using a third party IoC then it won’t understand how to convert that custom IoC code to the standard .NET 6 DI equivalent. It also won’t convert your EF 6 (NF) code to EF 7 (NET 6) code. All this is manual. Even the things it does modify will likely need to be updated. For example config files didn’t support hierarchy settings but JSON does so whereas you might have had an appsetting called
myclient.clientidbefore you would have the same thing in JSON but it would be cleaner to have it as a
myclientobject with a
clientidfield. And of course all this should be managed using
IOptions. The converter won’t handle any of this.
In my experience it works well for getting a realistic app’s core code migrated but it won’t compile when you’re done and it definitely won’t run. You should still plan to take a while to fix things. I tend to lean toward doing an inplace upgrade of libraries and then a side-by-side isolated for the core app so I can better understand what the original code was doing.
Until there is no methodology to replicate the session.onend() event it’s impossible to port certain .Net Framework applications. I understand the scalability, the cloud and bla bla bla but you should give devs a choice to use inproc & local.
Session in ASP.NET Core can be inproc or distributed. This is fully supported. Not sure what you meant by that. It is pretty much required in server farm scenarios.
Session end was never reliable even in .NET Framework so any code that relies on it could potentially not run anyway. This has always been true. If you need guaranteed cleanup of some session after it expires then this is probably better handled using a distributed cache and having the cache clean things up when it expires. At any point the web app could go down and no session cleanup would occur or the user could close the browser which would most likely wipe the session cookie but the server wouldn’t know. So you cannot really “clean up” anything inside the web app anyway. Of course this would only matter for resources that aren’t tied to memory.
Thanks for finally providing a graphical wizard in Visual Studio tradition of developer productivity.
Thanks! We received feedback that developers would like a GUI experience in VS and that’s why we’ve built it. Please keep giving us your feedback so we can create better products for you!
How does it upgrade a VB.Net WinForms LINQ-2-SQL project ?
It doesn’t. LINQ 2 SQL was deprecated a while back and isn’t supported in .NET 5+. Any code that relies on L2S would need to be updated to use newer technology. This would be part of the manual process the article mentions. The VB app could be upgraded though.
So for us this is useless. I’ve been searching for an article by MS that shows how to convert L2S to EF Core for instance but apparantly nobody ever bothered to make something like that.
I wouldn’t remain on a deprecated library just because nobody provided a walkthrough process. There are not many articles on converting from one database system to another and yet people do it quite a bit. Try this article for a starter though. At some point you are just going to have to rewrite the code but if you’ve properly architected your system then this is just a data layer change that shouldn’t impact the higher layer(s) and you could do this piecemeal if you have a really large code base. The one time we migrated from L2S to EF we were dealing with about 20 tables with a lot of relationships. Took about a week to migrate the code and do testing and a couple of weeks to retest the entire app.
Like others said, yes, a text a bit contradictory.
Looking forward for Xamarin => MAUI.
I have the intention to port some day, but now I will wait for this plugin update.
Even if the plugin only port 50%, it’s better than do 100% manual.
This plugin also works with Visual Studio for macOS ?
When you add the Xamarin => MAUI option do you also will annonce on this blog ?
Thanks! The work for it is in progress and I’ll publish a new blog post devoted to Xamarin – > MAUI migration once it is released.
For now, we are working on VS and not yet VS for Mac. We will listen to developers’ feedback to evaluate VS for Mac effort, so if it is crucial for you, you cannot port your app on Windows machine and need VS for Mac, please leave us a feature request in Visual Studio (top right corner).
You say ASP.NET from Framework, but that glosses over a pretty important concern: what does it do with ASP.NET Web Forms? My understanding is that the official MS position is that Web Forms aren’t ever coming to Core or modern .NET and therefore no automatic upgrade path is ever likely to be possible.
If that’s changed and there is now a supported upgrade path for Web Forms projects, that’s huge and fantastic news! On the other hand, if the ASP.NET from Framework option only covers the MVC family of APIs, that really ought to be called out in the article.
Thanks for pointing this out!
Yes, you’re right, as we announced before, Web Forms is not coming to .NET Core and later versions of .NET. We tried to only bring forward modern technologies into the modern .NET platforms. ASP.NET Web Forms is very functional (and still supported), but we don’t consider it a modern way to build web apps.
Few options to consider:
– we have a book on how you can rewrite your application using Blazor.
if you don’t want to make changes to your code, you can leave the app on .NET Framework.
if you still want to use Web Forms on the modern .NET platform, you can try a third-party solution https://coreforms.net from Rubicon.
I have a WPF .NET Framework 4.8 desktop Project that has been published to a number of users. If I upgrade the Project to .NET 6 (LTS) and re-publish, will users be prompted to instal .NET 6 or will the update fail on any user that doesn’t have it pre-installed? I am using ClickOnce for distributing new desktop versions.
I have port a WPF .NET Framework 4.7.2 project to .NET 6 that is distributed through ClickOnce. The ClickOnce configuration now is in independent files so you can have different profiles to different types of distribution.
One consideration point is the new requeriments of the application that now would require .NET 5, 6 or 7 that would need to be present in the client PC and ClickOnce doesn’t include new requeriments in update process. What I have done is to create the ClickOnce profile as framework independet so all the .NET components needed for the application are included with the ClickOnce distribution.
But once said that, if you create the ClickOnce profile with the same configuration as the previos one the update would be transparent for the client.
I think there’s an error in the blog post describing the three types of upgrade types. I believe it should read as follows:
Upgrade assistant supports 3 upgrade types. Different types are recommended for different project types, so you will see only those options that would work well for your app.
In-place. In this case your original project will be upgraded all at once. If you are using source control and prefer to manage the copies yourself, for example, by using branches, this option is for you.
Side-by-side. With this option your original project will be untouched, and a copy of it will be added to the solution which will contain the upgraded code. This type can be handy if your application has many dependencies that might be broken after the upgrade. This way you can check-in your progress and not worry about the application not building.
Side-by-side incremental. This is the ideal choice for web applications.Upgrade from ASP.NET to ASP.NET Core requires a lot of work and at times manual refactoring (because these two technologies are very different). …. etc….
Thank you! Yes, that got messed up. Fixed.
Hey, can the upgrade assistant extension migrate .net framework 4.8 .csproj files from old style to sdk style, keeping them .net framework 4.8? – this would be the first, manual step i’d want to do since we have a couple of framework-only dependencies and thus cannot migrate to “new” .net … yet.
Take a look at this third party tool. Personally I find it is easier to just migrate it manually as in most cases you are literally just removing a lot of what is in the project file. There are a few gotchas though like embedded resources, T4 templates and designer files. But it isn’t too hard.
Just be careful about what type of projects you migrate. For example if you migrate an app project and that project uses the Nuget packages.config file then switching to SDK will now use
PackageReference. But that newer format doesn’t support package install scripts. Therefore you run into cases where you might install a Nuget package and it might want to update your project config or settings to work with .NET Framework, but it can’t. So we follow the rule that we switch to SDK format for all project types except those that are for apps. We special case apps that don’t rely on any Nuget packages that would require config changes though.
An alternative approach is to run the upgrade assistant side-by-side to have it produce the new SDK project, then throw out the new project it generated and use the generated SDK project file for the old project.
Yes to everything that Michael Taylor said and also you can run Upgrade Assistant and then switch back your project to target .NET Framework, for some cases it would work. You can do it by simply replacing net6.0 to net48 in TargetFramework attribute in your project file.