 There's Tomas. Hey Tomas good to see you. Yeah, good to see you too. So webforms migrating To that network. That's exciting Yeah, everybody who has a webforms app is going to want to do this. Yeah, so you've got a really good topic here. Oh Thank you. So greetings everyone. I'm greeting you from Prague Czech Republic. My name is Thomas Herzeg I'm Microsoft MVP and CEO of Fraganti and I will show you one of the possible migration paths for ASP.net webforms application And how to get it to dotnet core First I would have to say that it's not a magic wizard or any other tool that you would magically run and it would Spit out working Application in dotnet core. Yeah from the from the webforms one it to will require some significant amount of work But it should be much easier than to rewrite the entire application from scratch That's why I have to without rewriting everything in the title. You will have to rewrite something but Hopefully we won't do a full rewrite Okay, so Every version of dotnet core has been filling some gaps of what was what was what was possible in a Dotnet framework and what's now possible in dotnet core and with dotnet core 3.0 we can do desktop applications in WinForms and WPF and we can also use entity framework 6 Which is also very popular and very widely used But there are some gaps that will probably never be filled For example ASP.net webforms, which won't be ported to dotnet core in the future, so You can you have basically two options you can keep running on dotnet framework, which is here, which will Be supported forever set Scott Hunter said forever but of course If you want to take advantage of some new things in dotnet core and there is plenty of Improvements for example the new project system the new get handling. It's much better in dotnet core projects than in old dotnet framework ones or some runtime improvements performance then dotnet core may have a lot of benefits for you and Maybe you will want to get away from webforms with the Small effort, so just replace webforms with something else to be able to run in dotnet core I have seen a lot of webforms applications that are more than 10 years old actually Some of them were started when dotnet framework 1.0 was here So it's almost 20 years old and one of the common Anti-patterns that can be found in a lot of webforms apps is the mixing of the business logic with the UI Manipulation, so we have a button underscore click method in your code behind and you are communicating with the database and also manipulating the UI which makes difficult to Replace the UI framework with some other technology, but still with a small bit of refactoring it can be possible and A lot of these applications. They are not perfect, but they are there and a lot of companies rely on them They are still used. They still need to be maintained. They still need some bug fixes and adding new features As the world evolves So it's not very easy to just throw them away and start building them from scratch And I have also done a consulting and help to other companies which were using webforms and I have found that a lot of teams Didn't had the new modern web skills because they are still working with quite old Technologies and they didn't have time to learn JavaScript and not only the language Which is quite a little which is easy to learn But all the ecosystem around JavaScript webpack and PM and all those tools there it and if you Look what do you need to know if you want to develop in the react or in Angular? It's quite a huge amount of knowledge that you need to adopt before you can effectively work in these technologies So there is the fundamental question if you want to rewrite the application from scratch Or if you want to try to modernize it and it's not only a technical decision It's also a business decision because there may be might be some constraints about budgets. I have often saw that Rewriting means that you need a second team that will be doing the new application Why while the current team is working on the old one? So it may not be viable to double the capacity of the project and keep it for Few years until the entire application is rewritten. So the modernization can be away It can take a few weeks. It can take a few months, but One of the advantages is that typically this modernization can be done by the team that already exists and knows all The business logic and knows the problem domain. So What would be the goals for the modernization? I think that the it's pretty obvious since Many things in dotnet core are same as the in the dotnet framework You can use entity framework 6 for example with the net core 3.0 So the only remaining piece in many web forms applications will be just the web forms and the system dot web So basically we need to replace everything which depends on system web with some other UI technology or library framework It can be anything there are plenty of choices But of course we would like to keep as most of the business logic as is because if you start refactoring and redoing also the business logic, then you are Revwriting almost everything. So if it's possible to keep most of the business logic as is it would be great and also what we are looking for is an incremental way of modernization because You need to still take care of the old application. You need to fix bugs and deploy it to production so we are looking for a method that can be done simultaneously with the Current development works on the project and after we replace web forms with something else There should be nothing that would prevent us from just going to dotnet core because most of the libraries We will be using will probably be Supported also on dotnet core. Thanks to dotnet standard So which UI framework? It's a difficult choice because there is plenty of really good and viable options If you are familiar with JavaScript and things around it, you may use Angular You may use react if you are adventurous enough to try a new technology. You can use blazer But all these technologies means that you will need your business logic Exposed to the client because the code is actually running on the client side So you here I have to take your business logic and build a rest API or some other kind of API in front of it and it may not be as easy As it seems because in many cases it won't be one-to-one The rest API may look a little bit differently than the current business logic because it's not a problem if the code behind Does 20 queries to the SQL database? But it can be a problem if the client side application would shoe 20 HTTP requests, which could be sequential because there would be some performance issues So you will need to redesign the rest API to better fit the user interface Because there will be a lot of round trips for every rest API call. So One of the options that can be used is a framework, which is called dotvvm and it's open source It's the name suggests it's using model view view model approach and it's a proud member of dotnet foundation it's developed on github and One of the advantages of this framework is that you don't need to expose your business logic as a rest API Because the view models are C sharp classes, which are running on the server and you see the database from the server So you can just use entity framework to get your data and you don't need to build rest API endpoints and making sure everything is running So this will help you to keep most of the business logic unchanged So it can mean less effort for the modernization and dotvm supports both dotnet framework and dotnet core So you can install it in existing web forms application and start migrating page after another page and after you are finished you can just switch to dotnet core because dotvvm is supported on both platforms and as a web forms developers you will be it will be very easy for you to learn dotvvm because it's it's it was founded more than five years ago and it was Inspired by web forms and it successfully got rid of all the hated things on web forms like the view state or unpredictable HTML that was rendered so dotvvm had solved these issues using knockout.js and other JavaScript libraries But most of the things can be done without the knowledge of JavaScript If you know JavaScript it will help you But if you don't know it you can just use HTML and C-Sharp and you will be able to work with dotvvm so the plan for the modernization will be Quite simple, but it can take a few weeks or months on a real-world existing project But first you need to install dotvvm NuGet packages in the project There are two of them and then until you get rid of all the web forms Pages you can just take some ASPx page rewrite it in in dotvvm syntax for the views it's similar It's but it's not the same and most importantly you will need to refactor the code behind files into view models It's also C-Sharp class. So Basically, you can just copy paste some code and change it So you won't manipulate the text boxes and other controls in the user interface But you will use data binding instead of that As a side effect you will get a view models which are testable So it can improve also the testability of your application And if your business logic is Mixed with the UI manipulation code This is also an opportunity to separate those things So you will end with a proper business layer as it should be done And after you get rid of web forms you can just change your CS approach to run on dotnet core If you want to see the differences between dotvvm and web forms syntax There is a page dotvvm.com web forms. I have it Here and there are the differences There is a code sample in web forms and code sample in dotvvm So as you can see we don't have the form element around the entire page in dotvvm We don't have run at server. You don't need To specify IDs on the controls. We don't have view state instead We have view models and so on and so on. So this is the cheat sheet Where you will see the differences, but the fundamental concepts are pretty similar as you will see later in the demo So enough talking. Let's get to some code. So I have a Simple web forms application. I have it already Running so it's basically Starter template for web forms. There are two pages the about and the home page and on the home page I have a list of a grid view with customers and I'm using entity framework 6 which is connected to my local SQL database. I can do sorting But as you can see it makes because it's web forms. It makes a full post back So I have to scroll all the time But I have also a paging. So it's web forms and There is the model folder, which I won't touch during the migration It's very simple, but let's assume that this is my business layer. So I'm not touching this I don't want to do anything in this. I just want to change the presentation Framework for something else. So here is the master page And I have two pages. One of them have grid view. The about page is very simple. Just few lines of text I have already done the first step I have installed two NuGet packages in the project. The first is .vvm.o-win and o-win is Just a pipeline which can be run on top of classic ASP.net And I also have Microsoft o-win host system web Which is important because it makes the side-by-side run of the o-win pipeline In which .vvm can run and the classic pipeline of the ASP.net web forms And it will basically put the o-win pipeline in front of the web forms So when the server gets the HTTP request, it will go first to the o-win pipeline And if .vvm can handle it, it will do all the things and if not, it will fall back to the original ASP.net pipeline so web forms can take care of the requests So I can just look at my routing code For example, I have the about page which is on the URL slash about and When .vvm will handle this request, it won't never get to the web forms So I can just create the about page in .vvm and keep this page running in web forms And it will still work and if the application would use authentication The Microsoft o-win host system web will make sure that the same user identity will be shared between the o-win Pipeline and the web forms pipeline So no matter if you will do the authentication from the o-win part or from the web forms part You will have basically the single sign on both technologies will see the same user the same roles and everything So the integration is done quite easily and the rest of the NuGet packages There are just the dependencies of one of those packages. I have installed I also have entity framework here and there are some default packages like jQuery .vm doesn't need it, but it was in the project template So some of the packages also come from the project template. Okay So I have also created the startup class for o-win Yeah, because o-win needs a one class which will be executed at the startup of the application and I'm configuring .vvm So I'm saying register .vvm middleware in the o-win pipeline and I'm pointing it to .vvm startup Which is a file that contains all the configuration of .vvm the routes user controls resources and other other stuff and Basically, that's it. Now I can create two folders. The first one is called views Oh, sorry, I have it already in the file system, but it's not included in project So I will have to just include it Okay, there I'm did it's correct and it's just a convention You can have .vm pages everywhere, but I'm just following this convention and the first thing We will need to do is to create a master page and I want my users Don't recognize that the the site is running on two different technologies So I need to make the master page looking exactly the same So I will use the same structure and I will use the same CSS. So let's do it I will add new item and If you install .vvm for visual studio, it's the extension that can be downloaded for free for from .vvm.com You will get item templates for .vvm pages. So I can create a master page I'm calling it site and It can create a view model for me automatically. So I have This page which is in .vvm syntax and this view model which is right now It's just a C sharp class nothing special. So I can create the same master page So let's copy everything from the webforms one except of this first directive So let's copy everything and let's paste it here and As I said, there are a few changes in the syntax. So we don't have the run at server So I can replace it for just empty string. Let's go. I don't need the form in my page because .vvm uses Ajax for all the communication with the server So nothing really special here and the extension also tells me that ASP content placeholder is not available in .vvm But the concept of master pages is same as in webforms So I just change the prefix to dot and we have the .vvm master page ready to go There is so one interesting thing that we have also support single page apps So if I use SP a content placeholder Instead of content placeholder, I would have single page app. You can try this Also, there is one important thing in webforms I have used this expression to just print out the title of the page in dot vvm I have to persist my state in the view model So I can I can put the title property in the vmodel and just create a data binding which would Which would reference this property from the vmodel. I can just have it created and If I press F12 Okay Here it is. I can change it to string and because in webforms, I often struggled with that I Forgot to set the title because when you create webforms page, this title is empty So all my pages didn't have title and in dot vvm you can make this class abstract because it's master page view model and this will basically require all the Specific pages which are using the master page. They will have to provide the title. So I have compile time check of Whether the title is present in the page or not So I'm binding to a view model property Okay, and at the bottom there was I'm printing the datetime now year and There is actually no reason to have this in the view model So I will use a different kind of binding which is called resource and Basically, this will just evaluate the C sharp expression placed here and just print it out in the output So now I have the master page for dot vvm and it will use the same styles So it will look exactly the same as in webforms. Now, let's create a normal page and I will be migrating the about page first So this is it. Let's create a view model automatically and also let's use the master page So I will just select the master page from the list and now I have my about view model and Because it's the abstract class. It requires me to provide the title. So about and If I look in the webforms page, I can just copy paste this into my dot vvm page And also I have to change the data binding Okay, so here we go and the last thing is I need to register the route for my dot vvm page So in the dot vvm startup, I say config route table add Name of the route is about The route URL will be about so it has to be the same as in webforms and the path is views slash about dot html and That's it if you after you migrate this project to dotnet core if you plan to Run it on linux, which is possible Make sure that the casing in this path is Exactly the same as in the file names because the paths in the file system on linux are case sensitive Yeah, so and also it's safer to use forward slashes both of them will work on windows But on linux, it's better to use this one. Okay, so let's let's run it I hope that I haven't forgot anything but right now We should have the same looking application The first the default page it's is still in webforms because we haven't registered route for that in dot vvm So this is still webforms as you can see it's doing full postbacks I have to scroll down after every action But if I click about it takes a little bit longer because the first request to dot vvm needs to make sure everything is started but if you look now the refresh it's Very fast and if you look here, there is no view state I'm now running this page in dot vvm, but the rest of the application which is still in webforms It works exactly the same. So this is the way how you can migrate one page after another And after you get rid of all webform stuff, you will be able to go to dotnet core Let's advance in time for a little bit I have also rewrited the default page. So I have it Completed here. So let's look how I worked with the grid view in webforms very quickly So I have I have been using the model binding So in my code behind there is function called my grid get data and I have specified some columns and Sort expressions and things like that Here I was just creating a new data context for Entity framework and in this my grid get data I need to specify all these parameters to make sure that sorting and paging will run and Webforms will find those parameters and fill the correct Values in them. So I'm just counting the total number of customers and then I'm just returning customers I have sorting and paging right here. And of course you should dispose your DB context Because we want to do the good things Okay, so this is very easy And if you look how the grid view looks in dot VVM, you will see that we have a similar control So it's dot grid view. We have a data source Which is pointing to a customer's collection in my view model I will show it in a minute and there are specification of the columns and also it's very similar We also have the template column so we can put anything in in the in the table And also we have a data pager control which is bound to the same collection and it will just render the pagination and in the view model it's Quite nice because I can use dependency injection so in the constructor of the view model you can request any services you will need and I have a property called customers in my view model and It's of type grid view data set. It could be just a list But a list is just a plain collection without sorting and paging grid view data set is a class which ships with dot VVM and It's basically a list of customers with some metadata for paging and sorting So I have the page size you can set also the page index And this is where the current page index is persisted in the view model and the sort expression So it means which column I am using for sorting and if you want to load data in the grid view data set And if you have I queryable, it's very simple because you can just say customers load from for a load from queryable And it will handle the sorting and paging automatically So we don't need to use order by and skip and take just pass I queryable and you are done If you are not using entity framework, you can work with the data set manually So you can just say items equals and put there a collection of the rows for the current page And you can look at the sorting options to sort expression or to paging options to know What's your page index? So if you are using plain SQL, you can you can just fill the collection in the grid view data set automatically manually using the C sharp code and these controls can work with the data set So if you change something in the pager, it will just set the new page index and it will indicate the refresh is required So when dot VVM will call the prerender function, it will load the new data for the page So that's it. This is my default page and when I when I run it You will see that it looks the same, but it's now in dot VVM So I have successfully get rid of all webforms stuff in my application and The first request takes a long time because entity framework six is Initializing and also the SP net pipeline. It's still there. It's not used anymore, but it's still there and Now I the paging looks a little bit differently because the controls are not exactly the same but they're very similar, but it should work and all the requests are done by edgex So when I am changing the sort order, I don't need to scroll to the top of the page If you look in the page source, there is no view state We just have the view model which is serialized and sent together with the page So that's it. Now. I have all parts of my application in dot VVM So there are no SPX pages. The only relict is this global ASIX where I'm just configuring the entity framework So I will need to move this elsewhere, but all other things There is nothing that would depend on system web. So you can just unload the project and basically Remove almost everything which is in the CS approach. Yeah, so it's as you can see it's very long But I have already done it. So as you can see now, you can just add netcore app 3.0 and I'm now using dot VVM dot ASP netcore So I have to change the NuGet package from dot VVM.OIN to dot VVM ASP netcore And I am using 2.4 which already supports dot netcore 3.0 If you will use the 2.3 you will have to be on dot netcore 2.2 But the 2.4 supports dot netcore 3.0. So that's it And I'm still using entity framework 6.3 which is also supported on dot netcore 3.0 And the views and view models are exactly the same. I have not touched anything here I haven't also touched anything in my business layer or Something like business layer because it's very trivial and the only change is in the startup file Where I have moved the line from the global ASAX I also need to configure the DB provider factory because it was done in web config In the previous project, but now on dot netcore we don't have web config and I'm just registering dot VVM In and the startup class and here in the configuring pipeline I'm just adding the dot VVM middleware and that's it. So Basically, I have replaced only the pages with pages done in another technology It's conceptually similar to web forms So it will be very easy to adopt and learn dot VVM for every web forms developer Because most of the controls are very similar or and they are even using the same names of the properties and You can do this migration over a few months and you can deploy the application at any time because These technologies can coexist together in one application So I have the last slide here just a link to our github repository we will be very glad for any feedback and If you go to dot VVM dot com slash modernize there are more information and the link to github repository with the project I have been just showing Make sure you will see all those branches because in every branch there is each step of the migration So the first branch is just plain web forms application. This is how it looks after you install dot VVM This is when the migration is in process. So some pages are migrated some are not This is how it looks like when the migration is complete and this is just a switch to the dotnet core So make sure you will visit all the branches to see all the steps in this process And of course we will be happy for any feedback and if you have any questions I would be happy to help you and wish you pleasant migration experience All right, Tomas. Thank you so much You know what it is it's a nice ramp It's a nice bridge for those web forms developers to get to dotnet core and still have a Application that looks very similar to where they started Yeah, we have been using this for a couple of our customers Mostly the banks and other institutions. So we have ported applications with hundreds of web forms pages and It wasn't easy still you had to rewrite a lot of things and the refactor the code behinds into view models but it was also an opportunity to make the application much more maintainable because The view models are testable so you can write integration tests for them And also you can do a smaller factoring of the of the business logic But still there's so much of it that you don't want to refactor or redo it From scratch. So it was a great method and it proved. Well if with some of our customers Well, thank you Tomas. It's been great having you here as part of dotnet conf and we'll see you next time. All right Thank you very much. See you. All right. Bye You