Upgraden van ASP.NET Framework naar ASP.NET Core
Waarom upgraden naar de nieuwste .NET
ASP.NET Core is het moderne webframework voor .NET. Hoewel ASP.NET Core veel overeenkomsten heeft met ASP.NET in .NET Framework, is het een nieuw framework dat volledig is herschreven. ASP.NET apps die zijn bijgewerkt naar ASP.NET Core, kunnen profiteren van verbeterde prestaties en toegang tot de nieuwste functies en mogelijkheden voor webontwikkeling.
updatemethoden voor ASP.NET Framework
De meeste niet-triviale ASP.NET Framework-apps moeten overwegen om de incrementele upgrade benadering te gebruiken. Voor meer informatie, zie Incrementele upgrade van ASP.NET naar ASP.NET Core.
Voor ASP.NET MVC- en Web-API-apps, zie Leer hoe je kunt upgraden van ASP.NET MVC en Web API naar ASP.NET Core MVC. Voor ASP.NET Framework Web Forms-apps, zie Leer hoe je van ASP.NET Web Forms naar ASP.NET Core kunt upgraden.
Patronen voor bedrijfsweb-apps
Zie Enterprise-web-app-patronenvoor hulp bij het maken van een betrouwbare, veilige, uitvoerbare, testbare en schaalbare ASP.NET Core-app. Er is een volledige voorbeeldweb-app van productiekwaliteit beschikbaar waarmee de patronen worden geïmplementeerd.
URI-decoderingsverschillen tussen ASP.NET tot ASP.NET Core
ASP.NET Core heeft de volgende URI-decoderingsverschillen met ASP.NET Framework:
ASCII | Gecodeerd | ASP.NET Core | ASP.NET Framework |
---|---|---|---|
\ |
%5C |
\ |
/ |
/ |
%2F |
%2F |
/ |
Bij het decoderen van %2F
op ASP.NET Core:
- Het hele pad wordt niet-gescaped, behalve
%2F
omdat het converteren naar/
de padstructuur zou wijzigen. Het kan pas worden gedecodeerd als het pad is gesplitst in segmenten.
Als u de waarde voor HttpRequest.Url
wilt genereren, gebruikt u new Uri(this.AspNetCoreHttpRequest.GetEncodedUrl());
om te voorkomen dat Uri
de waarden verkeerd interpreteert.
Gebruikersgeheimen migreren van ASP.NET Framework naar ASP.NET Core
Zie dit GitHub-probleem.
Dit artikel fungeert als referentiehandleiding voor het migreren van ASP.NET apps naar ASP.NET Core.
Visual Studio heeft hulpprogramma's waarmee u ASP.NET apps kunt migreren naar ASP.NET Core. Zie Migreren van ASP.NET naar ASP.NET Core in Visual Studiovoor meer informatie.
De .NET Upgrade Assistant is een opdrachtregelprogramma waarmee ASP.NET naar ASP.NET Core kan worden gemigreerd. Zie Overzicht van de .NET Upgrade Assistant en Een ASP.NET MVC-app upgraden naar .NET 6 met de .NET Upgrade Assistantvoor meer informatie.
Zie het ebook Bestaande ASP.NET-apps overzetten naar .NET Core- voor een uitgebreide handleiding voor overzetten.
Voorwaarden
Doelraamwerken
ASP.NET Core-projecten bieden ontwikkelaars de flexibiliteit van het richten op .NET Core, .NET Framework of beide. Zie Kiezen tussen .NET Core en .NET Framework voor server-apps om te bepalen welk doelframework het meest geschikt is.
Wanneer projecten zich richten op .NET Framework, moeten ze verwijzen naar afzonderlijke NuGet-pakketten.
Door te richten op .NET Core kunt u talloze expliciete pakketverwijzingen elimineren, dankzij de ASP.NET Core metapakket. Installeer de Microsoft.AspNetCore.App
metapackage in uw project:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
Wanneer de metapackage wordt gebruikt, worden er geen pakketten waarnaar wordt verwezen in de metapackage geïmplementeerd met de app. De .NET Core Runtime Store bevat deze assets en ze zijn vooraf gecompileerd om de prestaties te verbeteren. Zie Microsoft.AspNetCore.App metapackage voor ASP.NET Core voor meer informatie.
Verschillen in projectstructuur
De .csproj
-bestandsindeling is vereenvoudigd in ASP.NET Core. Enkele belangrijke wijzigingen zijn:
Expliciete opname van bestanden is niet nodig om ze als onderdeel van het project te beschouwen. Dit vermindert het risico dat XML-samenvoegingsconflicten optreden bij het werken aan grote teams.
Er zijn geen verwijzingen op basis van GUID naar andere projecten, waardoor de leesbaarheid van bestanden wordt verbeterd.
Het bestand kan worden bewerkt zonder het uit te lossen in Visual Studio:
]
Global.asax-bestandsvervanging
ASP.NET Core heeft een nieuw mechanisme geïntroduceerd voor het opstarten van een app. Het toegangspunt voor ASP.NET toepassingen is het bestand Global.asax. Taken zoals het configureren van routes, en het registreren van filters en gebieden worden afgehandeld in het bestand Global.asax.
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
Deze aanpak koppelt de toepassing en de server waarop deze is geïmplementeerd op een manier die de implementatie beïnvloedt. In een poging om OWIN- los te koppelen, is geïntroduceerd om een schonere manier te bieden om meerdere frameworks samen te gebruiken. OWIN biedt een pijplijn om alleen de benodigde modules toe te voegen. De hostingomgeving gebruikt een opstartfunctie om services en de aanvraagpijplijn van de app te configureren.
Startup
registreert een set middleware bij de toepassing. Voor elke aanvraag roept de toepassing elk van de middlewarecomponenten aan met de hoofdaanwijzer van een gekoppelde lijst naar een bestaande set afhandelaars. Elk middlewareonderdeel kan een of meer handlers toevoegen aan de pijplijn voor het verwerken van aanvragen. Dit wordt bereikt door een verwijzing te retourneren naar de handler die als nieuw hoofd van de lijst fungeert. Elke handler is verantwoordelijk voor het onthouden en aanroepen van de volgende handler in de lijst. Met ASP.NET Core is het toegangspunt voor een toepassing Startup
en hebt u geen afhankelijkheid meer van Global.asax. Wanneer u OWIN met .NET Framework gebruikt, gebruikt u iets als het volgende als een pijplijn:
using Owin;
using System.Web.Http;
namespace WebApi
{
// Note: By default all requests go through this OWIN pipeline. Alternatively you can turn this off by adding an appSetting owin:AutomaticAppStartup with value “false”.
// With this turned off you can still have OWIN apps listening on specific routes by adding routes in global.asax file using MapOwinPath or MapOwinRoute extensions on RouteTable.Routes
public class Startup
{
// Invoked once at startup to configure your application.
public void Configuration(IAppBuilder builder)
{
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute("Default", "{controller}/{customerID}", new { controller = "Customer", customerID = RouteParameter.Optional });
config.Formatters.XmlFormatter.UseXmlSerializer = true;
config.Formatters.Remove(config.Formatters.JsonFormatter);
// config.Formatters.JsonFormatter.UseDataContractJsonSerializer = true;
builder.UseWebApi(config);
}
}
}
Hiermee configureert u uw standaardroutes en geeft standaard XmlSerialization de voorkeur boven Json. Voeg indien nodig andere Middleware toe aan deze pijplijn (het laden van services, configuratie-instellingen, statische bestanden, enzovoort).
ASP.NET Core maakt gebruik van een vergelijkbare benadering, maar vertrouwt niet op OWIN om de vermelding af te handelen. In plaats daarvan wordt dat gedaan via de Program.cs
Main
-methode (vergelijkbaar met consoletoepassingen) en wordt Startup
daar geladen.
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
namespace WebApplication2
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}
Startup
moet een Configure
methode bevatten. Voeg in Configure
de benodigde middleware toe aan de pijplijn. In het volgende voorbeeld (van de standaardwebsitesjabloon) configureren extensiemethoden de pijplijn met ondersteuning voor:
- Foutpagina's
- HTTP Strict Transport Security
- HTTP-omleiding naar HTTPS
- ASP.NET Core MVC
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
De host en toepassing zijn ontkoppeld, wat de flexibiliteit biedt om in de toekomst over te stappen op een ander platform.
Notitie
Zie Startup in ASP.NET Core voor een uitgebreidere verwijzing naar ASP.NET Core Startup en Middleware
Configuraties opslaan
ASP.NET ondersteunt het opslaan van instellingen. Deze instelling wordt bijvoorbeeld gebruikt ter ondersteuning van de omgeving waarin de toepassingen zijn geïmplementeerd. Een veelvoorkomende procedure was het opslaan van alle aangepaste sleutel-waardeparen in de sectie <appSettings>
van het Web.config-bestand:
<appSettings>
<add key="UserName" value="User" />
<add key="Password" value="Password" />
</appSettings>
Toepassingen lezen deze instellingen met behulp van de verzameling ConfigurationManager.AppSettings
in de System.Configuration
-naamruimte:
string userName = System.Web.Configuration.ConfigurationManager.AppSettings["UserName"];
string password = System.Web.Configuration.ConfigurationManager.AppSettings["Password"];
ASP.NET Core kan configuratiegegevens voor de toepassing opslaan in elk bestand en laden als onderdeel van middleware bootstrapping. Het standaardbestand dat in de projectsjablonen wordt gebruikt, is appsettings.json
:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"AppConfiguration": {
"UserName": "UserName",
"Password": "Password"
}
}
Het laden van dit bestand in een exemplaar van IConfiguration
in uw toepassing wordt uitgevoerd in Startup.cs
:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
De app leest uit Configuration
om de instellingen op te halen:
string userName = Configuration.GetSection("AppConfiguration")["UserName"];
string password = Configuration.GetSection("AppConfiguration")["Password"];
Er zijn uitbreidingen voor deze aanpak om het proces robuuster te maken, zoals het gebruik van afhankelijkheidsinjectie (DI) om een service met deze waarden te laden. De DI-benadering biedt een sterk getypte set configuratieobjecten.
// Assume AppConfiguration is a class representing a strongly-typed version of AppConfiguration section
services.Configure<AppConfiguration>(Configuration.GetSection("AppConfiguration"));
Notitie
Zie Configuratie in ASP.NET Corevoor een uitgebreidere verwijzing naar ASP.NET Core-configuratie.
Systeemeigen afhankelijkheidsinjectie
Een belangrijk doel bij het bouwen van grote, schaalbare toepassingen is het losse koppelen van onderdelen en services. Afhankelijkheidsinjectie is een populaire techniek om dit te bereiken en het is een systeemeigen onderdeel van ASP.NET Core.
In ASP.NET-apps vertrouwen ontwikkelaars op een bibliotheek van derden om afhankelijkheidsinjectie te implementeren. Een dergelijke bibliotheek is Unity, geleverd door Microsoft Patterns & Practices.
Een voorbeeld van het configureren van dependency injection met Unity is het implementeren van IDependencyResolver
dat een UnityContainer
omvat:
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
container.Dispose();
}
}
Maak een exemplaar van uw UnityContainer
, registreer uw service en stel de afhankelijkheids resolver van HttpConfiguration
in op het nieuwe exemplaar van UnityResolver
voor uw container:
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
container.RegisterType<IProductRepository, ProductRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
// Other Web API configuration not shown.
}
Injecteer IProductRepository
indien nodig:
public class ProductsController : ApiController
{
private IProductRepository _repository;
public ProductsController(IProductRepository repository)
{
_repository = repository;
}
// Other controller methods not shown.
}
Omdat Afhankelijkheidsinjectie deel uitmaakt van ASP.NET Core, kunt u uw service toevoegen in de ConfigureServices
methode van Startup.cs
:
public void ConfigureServices(IServiceCollection services)
{
// Add application services.
services.AddTransient<IProductRepository, ProductRepository>();
}
De opslagplaats kan overal worden geïnjecteerd, zoals waar was met Unity.
Notitie
Zie Afhankelijkheidsinjectievoor meer informatie over afhankelijkheidsinjectie.
Statische bestanden verwerken
Een belangrijk onderdeel van webontwikkeling is de mogelijkheid om statische assets aan clientzijde te leveren. De meest voorkomende voorbeelden van statische bestanden zijn HTML, CSS, Javascript en afbeeldingen. Deze bestanden moeten worden opgeslagen op de gepubliceerde locatie van de app (of CDN) en waarnaar wordt verwezen, zodat ze kunnen worden geladen door een aanvraag. Dit proces is gewijzigd in ASP.NET Core.
In ASP.NET worden statische bestanden opgeslagen in verschillende mappen en waarnaar wordt verwezen in de weergaven.
In ASP.NET Core worden statische bestanden opgeslagen in de 'webhoofdmap' (<inhoudshoofdmap>/wwwroot), tenzij anders geconfigureerd. De bestanden worden in de aanvraagpijplijn geladen door de UseStaticFiles
-extensiemethode vanuit Startup.Configure
aan te roepen:
Notitie
Als u zich richt op .NET Framework, installeert u het NuGet-pakket Microsoft.AspNetCore.StaticFiles
.
Een afbeeldingsasset in de map wwwroot/images is bijvoorbeeld toegankelijk voor de browser op een locatie zoals http://<app>/images/<imageFileName>
.
Notitie
Zie Statische bestandenvoor een uitgebreidere verwijzing naar het leveren van statische bestanden in ASP.NET Core.
Cookies met meerdere waarden
cookies met meerdere waarden worden niet ondersteund in ASP.NET Core. Maak één cookie per waarde.
Verificatiecookies worden niet gecomprimeerd in ASP.NET Core
Om veiligheidsredenen worden verificatiecookies niet gecomprimeerd in ASP.NET Core. Bij het gebruik van verificatiecookies moeten ontwikkelaars het aantal opgenomen claimgegevens minimaliseren tot slechts datgene wat nodig is voor hun behoeften.
Gedeeltelijke app-migratie
Een benadering van gedeeltelijke app-migratie is het maken van een IIS-subtoepassing en alleen bepaalde routes van ASP.NET 4.x naar ASP.NET Core verplaatsen terwijl de URL-structuur van de app behouden blijft. Bekijk bijvoorbeeld de URL-structuur van de app uit het applicationHost.config-bestand:
<sites>
<site name="Default Web Site" id="1" serverAutoStart="true">
<application path="/">
<virtualDirectory path="/" physicalPath="D:\sites\MainSite\" />
</application>
<application path="/api" applicationPool="DefaultAppPool">
<virtualDirectory path="/" physicalPath="D:\sites\netcoreapi" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:80:" />
<binding protocol="https" bindingInformation="*:443:" sslFlags="0" />
</bindings>
</site>
...
</sites>
Mapstructuur:
.
├── MainSite
│ ├── ...
│ └── Web.config
└── NetCoreApi
├── ...
└── web.config
[BIND] en Invoerformatteerders
Vorige versies van ASP.NET het kenmerk [Bind]
gebruikt om te beschermen tegen overpostingsaanvallen.
invoeropmaakprogramma's werken anders in ASP.NET Core. Het kenmerk [Bind]
is niet meer ontworpen om overposting te voorkomen bij gebruik met invoerindelingen om JSON of XML te parseren. Deze kenmerken zijn van invloed op modelbinding wanneer de gegevensbron formuliergegevens zijn die zijn gepost met het x-www-form-urlencoded
inhoudstype.
Voor apps die JSON-gegevens posten op controllers en JSON Input Formatters gebruiken om de gegevens te parseren, raden we u aan het kenmerk [Bind]
te vervangen door een weergavemodel dat overeenkomt met de eigenschappen die zijn gedefinieerd door het kenmerk [Bind]
.