Migrera Web Forms till Blazor: skärm för skärm, utan att skriva om allt på en gång
Så migrerar du en ASP.NET Web Forms-applikation till Blazor och .NET 10 skärm för skärm bakom en proxy, vad som är lätt, vad som är svårt och hur du börjar.
Vlado Pandžić · Grundare · Senior .NET-arkitekt
Publicerad · 5 min läsning
Många företag kör fortfarande en viktig applikation på ASP.NET Web Forms: en orderportal, ett internt system för lagret eller administrationen, något som har fungerat i femton år. Det fungerar fortfarande. Men varje ändring tar längre tid, utvecklarna som kan systemet slutar, och ingen vill vara den som rör det.
Den goda nyheten: att gå över till Blazor behöver inte betyda ett år av omskrivning medan verksamheten väntar. Applikationen kan flyttas skärm för skärm, medan användarna fortsätter arbeta och knappt märker något.
Varför Web Forms inte bara kan uppgraderas
Web Forms finns inte i modern .NET. Det portades aldrig till ASP.NET Core, så det finns ingen knapp ”uppgradera till .NET 10”. Sidorna måste byggas om.
.NET Framework 4.8 stöds fortfarande så länge Windows-versionen det körs på stöds, så ingenting stängs av i morgon. Men det får inga nya funktioner, nya bibliotek hoppar allt oftare över det, och utvecklare som vill arbeta i Web Forms blir svårare att hitta för varje år.
Två vägar: allt på en gång, eller skärm för skärm
Allt på en gång verkar enklare: en ny applikation byggs vid sidan av den gamla och man byter över en dag. I praktiken innebär det månader utan nya funktioner i den gamla applikationen, två applikationer att underhålla parallellt och en driftsättning där allt måste fungera i samma ögonblick.
Skärm för skärm vänder på det. En proxy placeras framför den gamla applikationen, och varje skärm som flyttas till Blazor levereras sedan av den nya applikationen. Användarna har kvar samma adress och samma inloggning och går från gamla till nya skärmar utan att märka det.
- 1Inventering av alla skärmar
- 2Proxy framför den gamla applikationen
- 3Skärm för skärm till Blazor
- 4Den gamla applikationen stängs av
Proxyn: hur gammalt och nytt arbetar tillsammans
Proxyn är YARP, Microsofts reverse proxy, och den körs i den nya Blazor-applikationen. Allt som den nya applikationen kan leverera levererar den själv. Allt annat skickas vidare till den gamla Web Forms-applikationen.
builder.Services.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.MapReverseProxy();
I konfigurationen fångar en route upp alla adresser, med låg prioritet, så att den bara gäller när ingen Blazor-sida matchar:
"ReverseProxy": {
"Routes": {
"webforms": { "ClusterId": "webforms", "Order": 1000, "Match": { "Path": "{**catch-all}" } }
},
"Clusters": {
"webforms": { "Destinations": { "old": { "Address": "https://orders-legacy.internal/" } } }
}
}
När orderskärmen är ombyggd i Blazor börjar den nya applikationen leverera /orders, och den gamla skärmen nås helt enkelt inte längre. Inloggning och session kan delas mellan de två applikationerna med Microsofts System.Web-adaptrar, så att användarna inte behöver logga in två gånger.
Hur en skärm ser ut, före och efter
En typisk Web Forms-tabell med sidindelning:
<asp:GridView ID="OrdersGrid" runat="server" AutoGenerateColumns="false"
AllowPaging="true" PageSize="20" OnPageIndexChanging="OrdersGrid_PageIndexChanging">
<Columns>
<asp:BoundField DataField="Number" HeaderText="Order" />
<asp:BoundField DataField="Customer" HeaderText="Customer" />
<asp:BoundField DataField="Total" HeaderText="Total" DataFormatString="{0:C}" />
</Columns>
</asp:GridView>
Samma skärm i Blazor, med QuickGrid-komponenten som följer med .NET:
@inject OrderService Orders
<QuickGrid Items="orders" Pagination="pagination">
<PropertyColumn Property="@(o => o.Number)" Title="Order" />
<PropertyColumn Property="@(o => o.Customer)" Title="Customer" />
<PropertyColumn Property="@(o => o.Total)" Title="Total" Format="C" />
</QuickGrid>
<Paginator State="pagination" />
@code {
private readonly PaginationState pagination = new() { ItemsPerPage = 20 };
private IQueryable<Order> orders = Enumerable.Empty<Order>().AsQueryable();
protected override async Task OnInitializedAsync()
=> orders = (await Orders.GetOpenAsync()).AsQueryable();
}
Markupen ser liknande ut. Den verkliga skillnaden ligger bakom: ingen ViewState, ingen postback vid varje sidbyte, och OrderService är vanlig C# som kan testas och återanvändas.
Vad som flyttas lätt, och vad som inte gör det
| I Web Forms | I Blazor | Arbete |
|---|---|---|
| Affärslogik i separata klasser | Samma klasser, som tjänster | Litet |
| Affärslogik i code-behind | Flyttas först ut till tjänster | Medel |
| Master pages | Layouter | Litet |
| User controls (.ascx) | Komponenter | Litet till medel |
| GridView, Repeater, FormView | QuickGrid eller ett komponentbibliotek | Medel |
| Sidor byggda kring ViewState och postbacks | Komponenttillstånd, med ett omtänkt flöde | Medel |
| Web Forms-kontroller från tredje part | Deras Blazor-versioner, eller andra komponenter | Medel till stort |
| Crystal Reports | Ett annat rapportverktyg | Stort |
| Inloggning och session delad mellan gammalt och nytt | System.Web-adaptrar eller en delad cookie | Medel, en gång i början |
Den största osäkerheten är inte Blazor, utan hur mycket logik som ligger begravd i code-behind. Där logiken redan finns i separata klasser flyttas en skärm ofta på några dagar. Där varje knapptryck döljer hundra rader SQL och gränssnittskod blandat, måste den logiken först brytas ut.
I vilken ordning skärmarna flyttas
- Först en enkel skärm, för att visa att proxy, inloggning och driftsättning fungerar hela vägen.
- Sedan skärmarna som gör mest ont: de som ändras ofta, är långsamma eller som användarna klagar på. Där betalar sig flytten först.
- Sällan använda administrationsskärmar sist. Inventeringen hittar ofta skärmar som ingen använder längre, och de behöver inte flyttas alls.
Checklista innan du börjar
- En lista över alla sidor, med en notering om vilka som faktiskt används (loggar eller analys).
- NuGet-paket och kontroller från tredje part. Vårt kostnadsfria verktyg för .NET Framework-migrering kontrollerar vilka av dem som har en version för .NET 10.
- Hur inloggningen fungerar i dag: Forms-autentisering, Windows-autentisering eller ASP.NET Identity.
- Var affärslogiken finns: i separata klasser eller i code-behind.
- Rapporter, exporter och e-post som applikationen skickar.
- Vem som testar varje skärm när den flyttas, och vem som godkänner den.
För den större bilden av flytten från .NET Framework, läs artikeln om att migrera från .NET Framework till .NET 10, och för frågan om Blazor över huvud taget är ett säkert val, Har Blazor en framtid 2026?.
Så arbetar vi
Det är precis det vi gör: vi flyttar Web Forms-applikationer till Blazor skärm för skärm bakom en proxy, medan användarna fortsätter arbeta i applikationen. Vi börjar med en inventering och en plan som visar vilka skärmar som flyttas först och var de svåra delarna finns. Mer om arbetssättet finns på sidan Blazor, och första steget är ett kostnadsfritt samtal på 30 minuter.
Källor
- ASP.NET Framework to ASP.NET Core migration, Microsoft Learn
- Incremental ASP.NET to ASP.NET Core migration, Microsoft Learn
- YARP, GitHub
- System.Web adapters, GitHub
- ASP.NET Core Blazor QuickGrid component, Microsoft Learn
- .NET Framework lifecycle, Microsoft Learn
Den här artikeln är endast allmän information och inte juridisk, skattemässig, ekonomisk eller annan professionell rådgivning. Scenarier, exempel och beräkningar är illustrativa. Användarvillkor och ansvarsfriskrivning.