Recently, I have written a series of articles on modernizing ASP.NET Web Forms apps. Now this topic became even more important thanks to the recent announcement of .NET 5. It was made clear that ASP.NET Web Forms will not be ported to .NET Core.
TLDR: DotVVM can run side by side with ASP.NET Web Forms, and it also supports .NET core. You can install it in your Web Forms project and start rewriting individual pages from Web Forms to DotVVM (similar syntax and controls with MVVM approach) while still being able to add new features or deploy the app to the server. After all the Web Forms code is gone, you can just switch the project to .NET Core. See the sample repo.
To rewrite or continuously upgrade
There are still plenty of ASP.NET Web Forms applications out in the world and their authors now stand by a difficult decision:
- Throwing the old application away and rewrite it from scratch using modern stack
- Trying to continously modernize the app and rewrite all the pages on-the-fly
The first option – total rewrite – is very time consuming. If the original application was developed for more 10 years, which is not uncommon, I can hardly imagine that it can be rewritten it in less than half of that time. In addition, when the application needs to support company daily tasks and workflows while responding to rapidly changing business needs, it is impossible to stop adding new features for months or even years because of the rewrite.
Of course, the company can build a new team that will develop the new version while keeping the old team maintaining and extending the old app, but it means double effort and a vast amount of time required to transfer the domain knowledge from the old team to the new one. Also, many things will need to be done twice, and it will probably take years until the new version is ready for production.
And finally, the management never likes to hear about rewriting the software from scratch. I have seen many situations where the project leads had to fight very hard in order to justify such decision.
The second option – the continuos modernization – looks a little bit easier. Imagine you have a Web Forms application with hundreds of ASPX pages. If you can rewrite one page per day using other technology and integrate the new pages with the old ones so the user won’t notice they are made with different stacks, after several months you can get rid of all of the ASPX pages and stay with a more modern solution. It may not be perfect as there will still be some legacy code, but it is much better than nothing, and if you are lucky and don’t use WCF or Workflow Foundation which are also not supported on .NET Core, you will be able to move the project to .NET Core.
Two projects? Possible, but maybe more difficult than it has to be.
But how to do it? Let’s suppose we have an old app that needs to be maintained.
Shall we create a new ASP.NET Core project that would run side by side, maybe on the same domain, and make links from the old to new pages and vice versa?
It can work if the same CSS styles are used. The user should not be able to tell that he actually uses two web apps.
However, there may be some issues with sign-on as the new app can use different authentication cookies than the old one – the authentication will need to be integrated somehow. Also, if session is used (which is not a good idea in general, but it is also quite frequent), it will not be shared between the two applications.
Moreover, this will require some configuration changes on the server, and the deployment model will need to be changed as you will now deploy two applications instead of one.
If the application caches some data in memory, you may also run into various concurrency issues as the caches will need to be invalidated. There will also be some duplication if the business layer is not properly separated from the UI.
What is more, if you decide to use Angular, React or other JavaScript framework, there is also a large amount of knowledge required to start working with these technologies. The business logic and data will have to be exposed through a REST API (or Graph QL), which may be an additional effort to set up at the beginning.
DotVVM can make this simpler
What if there is a framework that can be run side by side with ASP.NET Web Forms in one application, but works also with the newest versions of ASP.NET Core?
It would make so many things easier. You will have just one project to deploy. There will be no changes in the deployment model – it will still be an ASP.NET application. You won’t need to take care about sharing the user identity between two apps because there won’t be two apps.
With DotVVM, it is quite easy. It was one of our initial thoughts that lead us to start with the project. If you haven’t heard of it – it is an open source MVVM framework supporting both ASP.NET and ASP.NET Core. It has nice Visual Studio integration and recently joined the .NET Foundation.
How does the migration work?
You can install DotVVM NuGet package in the Web Forms application and it will run side by side with the ASPX pages that are in the project.
From the deployment perspective, there are no changes – it is still the same ASP.NET application that gets deployed to the server as usual.
You can start with copying the Web Forms master page and converting it in the DotVVM syntax. It is different, but not much – most of the controls have the same names, except that you are using the MVVM approach. Use the same CSS so the users won’t notice the change.
Then, you can start rewriting all the pages one by one from Web Forms to DotVVM. DotVVM contains similar controls like GridView, Repeater, FileUpload and more. The most difficult part will be extracting the business logic from the ASPX code behind to the DotVVM viewmodel, but it is still C#.
If your business layer was propely separated, it should be trivial. If not, take this as an opportunity to do the refactoring and get the cleaner code. Thanks to the MVVM approach, your viewmodels will be testable and the overall quality of the application will greatly improve.
DotVVM pages will share the environment with the ASP.NET ones, including the current user identity. You won’t need to expose your business logic through a REST API, you can keep the same code interacting with the database.
At each point of the process, the application works, can be extended with new features, and can be deployed. The team is not locked to the migration and can do other things simultaneously.
After a few months, when all the ASPX pages are rewritten in DotVVM, you will be able to create a new ASP.NET Core project, move all DotVVM pages and viewmodels into it and use them with .NET Core. The syntax of DotVVM is the same on both platforms.
If you have been using Forms Authentication in Web Forms, you will need to switch it to ASP.NET Core Cookies, but that should be an easy-enough change.
Are there any samples?
Yes, I have created a GitHub repo which describes the process in detail. There are five branches, each one displaying one of the steps.
In the first one, there is a simple ASP.NET Web Forms application. In the last one, there is the same app rewritten in DotVVM and running on .NET Core.
We have used this way to migrate several Web Forms applications. If the business layer is separated properly, rewrite on one page takes about 1 hour in average. If the business logic is tighen up with the UI, it can take significantly more time, but it can be a way to improving the application testability and I think it is worth – even poorly written apps can be saved using this way.
What if I need help?
We’ll be happy to help you. You can also contact the DotVVM team on our Gitter chat. Check out the DotVVM documentation and the cheat-sheet of differences between Web Forms and DotVVM.