Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Dricks
Det här innehållet är ett utdrag ur e-boken, Blazor för ASP NET Web Forms Developers for Azure, tillgängligt på .NET Docs eller som en kostnadsfri nedladdningsbar PDF som kan läsas offline.
Att migrera en kodbas från ASP.NET webbformulär till Blazor är en tidskrävande uppgift som kräver planering. Det här kapitlet beskriver processen. Något som underlättar övergången är att se till att appen följer en N-nivåarkitektur , där appmodellen (i det här fallet Webbformulär) är skild från affärslogik. Den här logiska uppdelningen av lager gör det tydligt vad som behöver flyttas till .NET Core och Blazor.
I det här exemplet används eShop-appen som är tillgänglig på GitHub . eShop är en katalogtjänst som tillhandahåller CRUD-funktioner via formulärinmatning och validering.
Varför ska en fungerande app migreras till Blazor? Många gånger finns det inget behov. ASP.NET webbformulär kommer att fortsätta att stödjas i många år. Många av de funktioner som Blazor tillhandahåller stöds dock bara i en migrerad app. Sådana funktioner är:
- Prestandaförbättringar i ramverket, till exempel
Span<T> - Möjlighet att köra som WebAssembly
- Plattformsoberoende stöd för Linux och macOS
- Distribution av applokal distribution eller delat ramverk utan att påverka andra appar
Om dessa eller andra nya funktioner är tillräckligt övertygande kan det finnas ett värde i migreringen av appen. Migreringen kan ta olika former. Det kan vara hela appen eller bara vissa slutpunkter som kräver ändringarna. Beslutet att migrera baseras i slutändan på de affärsproblem som utvecklaren ska lösa.
Värdtjänster på serversidan och på klientsidan
Som beskrivs i kapitlet värdmodeller kan en Blazor app hanteras på två olika sätt: serversidan och klientsidan. Modellen på serversidan använder ASP.NET Core SignalR-anslutningar för att hantera DOM-uppdateringarna när du kör eventuell faktisk kod på servern. Modellen på klientsidan körs som WebAssembly i en webbläsare och kräver inga serveranslutningar. Det finns ett antal skillnader som kan påverka vilket som är bäst för en specifik app:
- Körs som WebAssembly stöder inte alla funktioner (till exempel trådning) för tillfället
- Chattig kommunikation mellan klienten och servern kan orsaka problem med svarstid i läget på serversidan
- Åtkomst till databaser och interna eller skyddade tjänster kräver en separat tjänst med värdtjänster på klientsidan
I skrivande stund liknar modellen på serversidan mer webbformulär. Det mesta av det här kapitlet fokuserar på värdmodellen på serversidan eftersom den är produktionsklar.
Skapa ett nytt projekt
Det här första migreringssteget är att skapa ett nytt projekt. Den här projekttypen baseras på SDK-formatprojekten i .NET och förenklar mycket av den pannplåt som användes i tidigare projektformat. Mer information finns i kapitlet om projektstruktur.
När projektet har skapats installerar du de bibliotek som användes i föregående projekt. I äldre Web Forms-projekt kan du ha använt filen packages.config för att visa de nödvändiga NuGet-paketen. I det nya SDK-projektet har packages.config ersatts med <PackageReference> element i projektfilen. En fördel med den här metoden är att alla beroenden installeras transitivt. Du listar bara de beroenden på den översta nivån som du bryr dig om.
Många av de beroenden du använder är tillgängliga för .NET, inklusive Entity Framework 6 och log4net. Om det inte finns någon tillgänglig .NET- eller .NET Standard-version kan .NET Framework-versionen ofta användas. Din körsträcka kan variera. Alla API:er som används som inte är tillgängliga i .NET orsakar ett körningsfel. Visual Studio meddelar dig om sådana paket. En gul ikon visas på projektets nod Referenser i Solution Explorer.
I det Blazor-baserade eShop-projektet kan du se de paket som är installerade. Tidigare listade filen packages.config varje paket som användes i projektet, vilket resulterade i en fil som var nästan 50 rader lång. Ett kodfragment av packages.config är:
<?xml version="1.0" encoding="utf-8"?>
<packages>
...
<package id="Microsoft.ApplicationInsights.Agent.Intercept" version="2.4.0" targetFramework="net472" />
<package id="Microsoft.ApplicationInsights.DependencyCollector" version="2.9.1" targetFramework="net472" />
<package id="Microsoft.ApplicationInsights.PerfCounterCollector" version="2.9.1" targetFramework="net472" />
<package id="Microsoft.ApplicationInsights.Web" version="2.9.1" targetFramework="net472" />
<package id="Microsoft.ApplicationInsights.WindowsServer" version="2.9.1" targetFramework="net472" />
<package id="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" version="2.9.1" targetFramework="net472" />
<package id="Microsoft.AspNet.FriendlyUrls" version="1.0.2" targetFramework="net472" />
<package id="Microsoft.AspNet.FriendlyUrls.Core" version="1.0.2" targetFramework="net472" />
<package id="Microsoft.AspNet.ScriptManager.MSAjax" version="5.0.0" targetFramework="net472" />
<package id="Microsoft.AspNet.ScriptManager.WebForms" version="5.0.0" targetFramework="net472" />
...
<package id="System.Memory" version="4.5.1" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.0" targetFramework="net472" />
<package id="System.Threading.Channels" version="4.5.0" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net472" />
<package id="WebGrease" version="1.6.0" targetFramework="net472" />
</packages>
Elementet <packages> innehåller alla nödvändiga beroenden. Det är svårt att identifiera vilka av dessa paket som ingår eftersom du behöver dem. Vissa <package> element visas bara för att uppfylla behoven hos beroenden som du behöver.
Projektet Blazor visar de beroenden som du behöver i ett <ItemGroup> element i projektfilen:
<ItemGroup>
<PackageReference Include="Autofac" Version="4.9.3" />
<PackageReference Include="EntityFramework" Version="6.4.4" />
<PackageReference Include="log4net" Version="2.0.12" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="2.2.12" />
</ItemGroup>
Ett NuGet-paket som förenklar livslängden för webbformulärutvecklare är Windows Compatibility Pack. Även om .NET är plattformsoberoende är vissa funktioner endast tillgängliga i Windows. Windows-specifika funktioner görs tillgängliga genom att installera kompatibilitetspaketet. Exempel på sådana funktioner är Registry, WMI och Directory Services. Paketet lägger till cirka 20 000 API:er och aktiverar många tjänster som du kanske redan är bekant med. eShop-projektet kräver inte kompatibilitetspaketet. men om dina projekt använder Windows-specifika funktioner underlättar paketet migreringsarbetet.
Aktivera startprocess
Startprocessen för Blazor har ändrats från Webbformulär och följer en liknande konfiguration för andra ASP.NET Core-tjänster. När razor-komponenter finns på serversidan körs de som en del av en vanlig ASP.NET Core-app. När razor-komponenter finns i webbläsaren med WebAssemblyanvänder de en liknande värdmodell. Skillnaden är att komponenterna körs som en separat tjänst från någon av serverdelsprocesserna. Hur som helst är starten liknande.
Filen Global.asax.cs är standardstartsidan för webbformulärprojekt. I eShop-projektet konfigurerar den här filen IoC-containern (Inversion of Control) och hanterar de olika livscykelhändelserna för appen eller begäran. Vissa av dessa händelser hanteras med mellanprogram (till exempel Application_BeginRequest). Andra händelser kräver att specifika tjänster åsidosätts via beroendeinmatning (DI).
Som exempel innehåller filen Global.asax.cs för eShop följande kod:
public class Global : HttpApplication, IContainerProviderAccessor
{
private static readonly ILog _log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
static IContainerProvider _containerProvider;
IContainer container;
public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
}
protected void Application_Start(object sender, EventArgs e)
{
// Code that runs on app startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ConfigureContainer();
ConfigDataBase();
}
/// <summary>
/// Track the machine name and the start time for the session inside the current session
/// </summary>
protected void Session_Start(Object sender, EventArgs e)
{
HttpContext.Current.Session["MachineName"] = Environment.MachineName;
HttpContext.Current.Session["SessionStartTime"] = DateTime.Now;
}
/// <summary>
/// https://autofaccn.readthedocs.io/en/latest/integration/webforms.html
/// </summary>
private void ConfigureContainer()
{
var builder = new ContainerBuilder();
var mockData = bool.Parse(ConfigurationManager.AppSettings["UseMockData"]);
builder.RegisterModule(new ApplicationModule(mockData));
container = builder.Build();
_containerProvider = new ContainerProvider(container);
}
private void ConfigDataBase()
{
var mockData = bool.Parse(ConfigurationManager.AppSettings["UseMockData"]);
if (!mockData)
{
Database.SetInitializer<CatalogDBContext>(container.Resolve<CatalogDBInitializer>());
}
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
//set the property to our new object
LogicalThreadContext.Properties["activityid"] = new ActivityIdHelper();
LogicalThreadContext.Properties["requestinfo"] = new WebRequestInfo();
_log.Debug("Application_BeginRequest");
}
}
Föregående fil blir den Program.cs filen på serversidan Blazor:
using eShopOnBlazor.Models;
using eShopOnBlazor.Models.Infrastructure;
using eShopOnBlazor.Services;
using log4net;
using System.Data.Entity;
using eShopOnBlazor;
var builder = WebApplication.CreateBuilder(args);
// add services
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
if (builder.Configuration.GetValue<bool>("UseMockData"))
{
builder.Services.AddSingleton<ICatalogService, CatalogServiceMock>();
}
else
{
builder.Services.AddScoped<ICatalogService, CatalogService>();
builder.Services.AddScoped<IDatabaseInitializer<CatalogDBContext>, CatalogDBInitializer>();
builder.Services.AddSingleton<CatalogItemHiLoGenerator>();
builder.Services.AddScoped(_ => new CatalogDBContext(builder.Configuration.GetConnectionString("CatalogDBContext")));
}
var app = builder.Build();
new LoggerFactory().AddLog4Net("log4Net.xml");
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
// Middleware for Application_BeginRequest
app.Use((ctx, next) =>
{
LogicalThreadContext.Properties["activityid"] = new ActivityIdHelper(ctx);
LogicalThreadContext.Properties["requestinfo"] = new WebRequestInfo(ctx);
return next();
});
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
ConfigDataBase(app);
void ConfigDataBase(IApplicationBuilder app)
{
using (var scope = app.ApplicationServices.CreateScope())
{
var initializer = scope.ServiceProvider.GetService<IDatabaseInitializer<CatalogDBContext>>();
if (initializer != null)
{
Database.SetInitializer(initializer);
}
}
}
app.Run();
En betydande ändring som du kanske märker från Web Forms är den framträdande beroendeinmatningen (DI). DI har varit en vägledande princip i ASP.NET Core-designen. Det stöder anpassning av nästan alla aspekter av ASP.NET Core-ramverket. Det finns till och med en inbyggd tjänstleverantör som kan användas i många scenarier. Om det krävs mer anpassning kan det stödjas av många communityprojekt. Du kan till exempel överföra din di-biblioteksinvestering från tredje part.
I den ursprungliga eShop-appen finns det en konfiguration för sessionshantering. Eftersom serversidan Blazor använder ASP.NET Core SignalR för kommunikation stöds inte sessionstillståndet eftersom anslutningarna kan ske oberoende av en HTTP-kontext. En app som använder sessionstillståndet kräver omarkitektur innan den körs som en Blazor app.
Mer information om appstart finns i Appstart.
Migrera HTTP-moduler och -hanterare till mellanprogram
HTTP-moduler och -hanterare är vanliga mönster i webbformulär för att styra HTTP-begärandepipelinen. Klasser som implementerar IHttpModule eller IHttpHandler kan registreras och bearbeta inkommande begäranden. Webbformulär konfigurerar moduler och hanterare i filen web.config . Web Forms är också starkt baserat på händelsehantering för appens livscykel. ASP.NET Core använder mellanprogram i stället. Mellanprogram registreras i Configure -metoden för Startup klassen. Körningsordningen för mellanprogram bestäms av registreringsordern.
I avsnittet Aktivera startprocess skapades en livscykelhändelse av Web Forms som Application_BeginRequest metod. Den här händelsen är inte tillgänglig i ASP.NET Core. Ett sätt att uppnå det här beteendet är att implementera mellanprogram enligt Startup.cs filexemplet. Det här mellanprogrammet gör samma logik och överför sedan kontrollen till nästa hanterare i pipelinen för mellanprogram.
Mer information om hur du migrerar moduler och hanterare finns i Migrera HTTP-hanterare och moduler till ASP.NET Core-mellanprogram.
Migrera statiska filer
För att kunna hantera statiska filer (till exempel HTML, CSS, bilder och JavaScript) måste filerna exponeras med mellanprogram.
UseStaticFiles Om du anropar metoden kan du hantera statiska filer från webbrotsökvägen. Standardkatalogen för webbrot är wwwroot, men den kan anpassas. Som ingår i Program.cs-filen:
...
app.UseStaticFiles();
...
EShop-projektet möjliggör grundläggande statisk filåtkomst. Det finns många anpassningar för åtkomst till statiska filer. Information om hur du aktiverar standardfiler eller en filwebbläsare finns i Statiska filer i ASP.NET Core.
Migrera konfiguration av runtime-paketering och minifiering
Paketering och minifiering är prestandaoptimeringstekniker för att minska antalet och storleken på serverbegäranden för att hämta vissa filtyper. JavaScript och CSS genomgår ofta någon form av paketering eller minifiering innan de skickas till klienten. I ASP.NET webbformulär hanteras dessa optimeringar vid körning. Optimeringskonventionerna definieras som en App_Start/BundleConfig.cs fil. I ASP.NET Core används en mer deklarativ metod. En fil visar de filer som ska minifieras, tillsammans med specifika minifieringsinställningar.
Mer information om paketering och minifiering finns i Paketera och minimera statiska tillgångar i ASP.NET Core.
Migrera ASPX-sidor
En sida i en webbformulärapp är en fil med tillägget .aspx . En webbformulärsida kan ofta mappas till en komponent i Blazor. En Razor-komponent skapas i en fil med .razor-tillägget . För eShop-projektet konverteras fem sidor till en Razor-sida.
Informationsvyn består till exempel av tre filer i projektet Webbformulär: Details.aspx, Details.aspx.cs och Details.aspx.designer.cs. När du konverterar till Blazorkombineras koden bakom och pålägget till Details.razor. Razor-kompilering (motsvarar vad som finns i .designer.cs filer) lagras i katalogen obj och kan som standard inte visas i Solution Explorer. Sidan Webbformulär består av följande markering:
<%@ Page Title="Details" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Details.aspx.cs" Inherits="eShopLegacyWebForms.Catalog.Details" %>
<asp:Content ID="Details" ContentPlaceHolderID="MainContent" runat="server">
<h2 class="esh-body-title">Details</h2>
<div class="container">
<div class="row">
<asp:Image runat="server" CssClass="col-md-6 esh-picture" ImageUrl='<%#"/Pics/" + product.PictureFileName%>' />
<dl class="col-md-6 dl-horizontal">
<dt>Name
</dt>
<dd>
<asp:Label runat="server" Text='<%#product.Name%>' />
</dd>
<dt>Description
</dt>
<dd>
<asp:Label runat="server" Text='<%#product.Description%>' />
</dd>
<dt>Brand
</dt>
<dd>
<asp:Label runat="server" Text='<%#product.CatalogBrand.Brand%>' />
</dd>
<dt>Type
</dt>
<dd>
<asp:Label runat="server" Text='<%#product.CatalogType.Type%>' />
</dd>
<dt>Price
</dt>
<dd>
<asp:Label CssClass="esh-price" runat="server" Text='<%#product.Price%>' />
</dd>
<dt>Picture name
</dt>
<dd>
<asp:Label runat="server" Text='<%#product.PictureFileName%>' />
</dd>
<dt>Stock
</dt>
<dd>
<asp:Label runat="server" Text='<%#product.AvailableStock%>' />
</dd>
<dt>Restock
</dt>
<dd>
<asp:Label runat="server" Text='<%#product.RestockThreshold%>' />
</dd>
<dt>Max stock
</dt>
<dd>
<asp:Label runat="server" Text='<%#product.MaxStockThreshold%>' />
</dd>
</dl>
</div>
<div class="form-actions no-color esh-link-list">
<a runat="server" href='<%# GetRouteUrl("EditProductRoute", new {id =product.Id}) %>' class="esh-link-item">Edit
</a>
|
<a runat="server" href="~" class="esh-link-item">Back to list
</a>
</div>
</div>
</asp:Content>
Kod bakom ovanstående kod innehåller följande kod:
using eShopLegacyWebForms.Models;
using eShopLegacyWebForms.Services;
using log4net;
using System;
using System.Web.UI;
namespace eShopLegacyWebForms.Catalog
{
public partial class Details : System.Web.UI.Page
{
private static readonly ILog _log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
protected CatalogItem product;
public ICatalogService CatalogService { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
var productId = Convert.ToInt32(Page.RouteData.Values["id"]);
_log.Info($"Now loading... /Catalog/Details.aspx?id={productId}");
product = CatalogService.FindCatalogItem(productId);
this.DataBind();
}
}
}
När den konverteras till Blazoröversätts sidan Webbformulär till följande kod:
@page "/Catalog/Details/{id:int}"
@inject ICatalogService CatalogService
@inject ILogger<Details> Logger
<h2 class="esh-body-title">Details</h2>
<div class="container">
<div class="row">
<img class="col-md-6 esh-picture" src="@($"/Pics/{_item.PictureFileName}")">
<dl class="col-md-6 dl-horizontal">
<dt>
Name
</dt>
<dd>
@_item.Name
</dd>
<dt>
Description
</dt>
<dd>
@_item.Description
</dd>
<dt>
Brand
</dt>
<dd>
@_item.CatalogBrand.Brand
</dd>
<dt>
Type
</dt>
<dd>
@_item.CatalogType.Type
</dd>
<dt>
Price
</dt>
<dd>
@_item.Price
</dd>
<dt>
Picture name
</dt>
<dd>
@_item.PictureFileName
</dd>
<dt>
Stock
</dt>
<dd>
@_item.AvailableStock
</dd>
<dt>
Restock
</dt>
<dd>
@_item.RestockThreshold
</dd>
<dt>
Max stock
</dt>
<dd>
@_item.MaxStockThreshold
</dd>
</dl>
</div>
<div class="form-actions no-color esh-link-list">
<a href="@($"/Catalog/Edit/{_item.Id}")" class="esh-link-item">
Edit
</a>
|
<a href="/" class="esh-link-item">
Back to list
</a>
</div>
</div>
@code {
private CatalogItem _item;
[Parameter]
public int Id { get; set; }
protected override void OnInitialized()
{
Logger.LogInformation("Now loading... /Catalog/Details/{Id}", Id);
_item = CatalogService.FindCatalogItem(Id);
}
}
Observera att koden och pålägget finns i samma fil. Alla nödvändiga tjänster görs tillgängliga med attributet @inject . Enligt direktivet @page kan den här sidan nås på Catalog/Details/{id} vägen. Värdet för vägens {id} platshållare har begränsats till ett heltal. Som beskrivs i routningsavsnittet, till skillnad från Web Forms, anger en Razor-komponent uttryckligen dess väg och eventuella parametrar som ingår. Många Web Forms-kontroller kanske inte har exakta motsvarigheter i Blazor. Det finns ofta ett motsvarande HTML-kodfragment som har samma syfte. Kontrollen kan till exempel <asp:Label /> ersättas med ett HTML-element <label> .
Modellverifiering i Blazor
Om webbformulärkoden innehåller validering kan du överföra mycket av det du har med små eller inga ändringar. En fördel med att köra i Blazor är att samma valideringslogik kan köras utan att behöva anpassad JavaScript. Dataanteckningar möjliggör enkel modellverifiering.
Sidan Create.aspx har till exempel ett formulär för datainmatning med validering. Ett exempelfragment skulle se ut så här:
<div class="form-group">
<label class="control-label col-md-2">Name</label>
<div class="col-md-3">
<asp:TextBox ID="Name" runat="server" CssClass="form-control"></asp:TextBox>
<asp:RequiredFieldValidator runat="server" ControlToValidate="Name" Display="Dynamic"
CssClass="field-validation-valid text-danger" ErrorMessage="The Name field is required." />
</div>
</div>
I Blazoranges motsvarande markering i en Create.razor-fil :
<EditForm Model="_item" OnValidSubmit="@...">
<DataAnnotationsValidator />
<div class="form-group">
<label class="control-label col-md-2">Name</label>
<div class="col-md-3">
<InputText class="form-control" @bind-Value="_item.Name" />
<ValidationMessage For="(() => _item.Name)" />
</div>
</div>
...
</EditForm>
Kontexten EditForm innehåller valideringsstöd och kan omslutas kring indata. Dataanteckningar är ett vanligt sätt att lägga till validering. Sådant valideringsstöd kan läggas till via komponenten DataAnnotationsValidator . Mer information om den här mekanismen finns i ASP.NET Core-formulär Blazor och -validering.
Migrera konfiguration
I ett Web Forms-projekt lagras konfigurationsdata oftast i filen web.config . Konfigurationsdata nås med ConfigurationManager. Tjänster krävdes ofta för att parsa objekt. Med .NET Framework 4.7.2 lades komposterbarheten till i konfigurationen via ConfigurationBuilders. Dessa byggare tillät utvecklare att lägga till olika källor för konfigurationen som sedan komponerades vid körning för att hämta nödvändiga värden.
ASP.NET Core introducerade ett flexibelt konfigurationssystem som gör att du kan definiera den konfigurationskälla eller de källor som används av din app och distribution. Infrastrukturen ConfigurationBuilder som du kanske använder i webbformulärappen har modellerats efter de begrepp som används i konfigurationssystemet ASP.NET Core.
Följande kodfragment visar hur Web Forms eShop-projektet använder web.config för att lagra konfigurationsvärden:
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="CatalogDBContext" connectionString="Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb; Integrated Security=True; MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="UseMockData" value="true" />
<add key="UseCustomizationData" value="false" />
</appSettings>
</configuration>
Det är vanligt att hemligheter, till exempel databas anslutningssträng, lagras i web.config. Hemligheterna bevaras oundvikligen på osäkra platser, till exempel källkontroll. Med Blazor på ASP.NET Core ersätts den föregående XML-baserade konfigurationen med följande JSON:
{
"ConnectionStrings": {
"CatalogDBContext": "Data Source=(localdb)\\MSSQLLocalDB; Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb; Integrated Security=True; MultipleActiveResultSets=True;"
},
"UseMockData": true,
"UseCustomizationData": false
}
JSON är standardkonfigurationsformatet. men ASP.NET Core stöder många andra format, inklusive XML. Det finns också flera format som stöds av communityn.
Du kan komma åt konfigurationsvärden från byggaren i Program.cs:
if (builder.Configuration.GetValue<bool>("UseMockData"))
{
builder.Services.AddSingleton<ICatalogService, CatalogServiceMock>();
}
else
{
builder.Services.AddScoped<ICatalogService, CatalogService>();
builder.Services.AddScoped<IDatabaseInitializer<CatalogDBContext>, CatalogDBInitializer>();
builder.Services.AddSingleton<CatalogItemHiLoGenerator>();
builder.Services.AddScoped(_ => new CatalogDBContext(builder.Configuration.GetConnectionString("CatalogDBContext")));
}
Som standard miljövariabler, JSON-filer (appsettings.json och apparinställningar.{ Environment}.json) och kommandoradsalternativ registreras som giltiga konfigurationskällor i konfigurationsobjektet. Konfigurationskällorna kan nås via Configuration[key]. En mer avancerad teknik är att binda konfigurationsdata till objekt med hjälp av alternativmönstret. Mer information om konfiguration och alternativmönster finns i Konfiguration i ASP.NET Core respektive Alternativ i ASP.NET Core.
Migrera dataåtkomst
Dataåtkomst är en viktig aspekt av alla appar. eShop-projektet lagrar kataloginformation i en databas och hämtar data med Entity Framework (EF) 6. Eftersom EF 6 stöds i .NET 5 kan projektet fortsätta att använda det.
Följande EF-relaterade ändringar var nödvändiga för eShop:
- I .NET Framework
DbContextaccepterar objektet en sträng med formulärnamnet=ConnectionString och använder anslutningssträng frånConfigurationManager.AppSettings[ConnectionString]för att ansluta. I .NET Core stöds inte detta. Anslutningssträng måste anges. - Databasen användes på ett synkront sätt. Även om detta fungerar kan skalbarheten bli lidande. Den här logiken bör flyttas till ett asynkront mönster.
Även om det inte finns samma inbyggda stöd för datamängdsbindning ger Blazor det flexibilitet och kraft med C#-stöd på en Razor-sida. Du kan till exempel utföra beräkningar och visa resultatet. Mer information om datamönster i finns i Blazoravsnittet Dataåtkomst.
Ändringar i arkitekturen
Slutligen finns det några viktiga arkitekturskillnader att tänka på när du migrerar till Blazor. Många av dessa ändringar gäller för allt som baseras på .NET Core eller ASP.NET Core.
Eftersom Blazor bygger på .NET Core finns det saker att tänka på när det gäller att säkerställa stöd för .NET Core. Några av de viktigaste ändringarna omfattar borttagning av följande funktioner:
- Flera AppDomains
- Fjärrkommunikation
- Kodåtkomstsäkerhet (CAS)
- Säkerhetstransparens
Mer information om tekniker för att identifiera nödvändiga ändringar som stöder körning på .NET Core finns i Porta koden från .NET Framework till .NET Core.
ASP.NET Core är en ny version av ASP.NET och har vissa ändringar som kanske inte verkar uppenbara från början. De viktigaste ändringarna är:
- Ingen synkroniseringskontext, vilket innebär att det inte finns några
HttpContext.Current,Thread.CurrentPrincipaleller andra statiska accessorer - Ingen skuggkopiering
- Ingen kö för begäran
Många åtgärder i ASP.NET Core är asynkrona, vilket möjliggör enklare inläsning av I/O-bundna uppgifter. Det är viktigt att aldrig blockera med hjälp Task.Wait() av eller Task.GetResult(), vilket snabbt kan tömma trådpoolresurser.
Migreringsavslut
Nu har du sett många exempel på vad som krävs för att flytta ett webbformulärprojekt till Blazor. Ett fullständigt exempel finns i projektet eShopOnBlazor .