Anteckning
Å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.
HttpContext är en grundläggande komponent i webbprogram som ger åtkomst till HTTP-begäran och svarsinformation. När du migrerar från ASP.NET Framework till ASP.NET Core innebär HttpContext unika utmaningar eftersom de två ramverken har olika API:er och metoder.
Varför HttpContext-migrering är komplex
ASP.NET Framework och ASP.NET Core har fundamentalt olika HttpContext-implementeringar:
- ASP.NET Framework använder System.Web.HttpContext med inbyggda egenskaper och metoder
- ASP.NET Core använder Microsoft.AspNetCore.Http.HttpContext med en mer modulär, utökningsbar design
Dessa skillnader innebär att du inte bara kan flytta din HttpContext-kod från Framework till Core utan ändringar.
Översikt över migreringsstrategier
Du har två huvudsakliga metoder för att hantera HttpContext under migreringen:
- Fullständig omskrivning – Skriv om all HttpContext-kod för att använda ASP.NET Cores interna HttpContext-implementering
- System.Web-adaptrar – Använd adaptrar för att minimera kodändringar vid migrering stegvis
För de flesta program ger migrering till ASP.NET Cores interna HttpContext bästa prestanda och underhållsbarhet. Större program eller program med omfattande HttpContext-användning kan dock ha nytta av att använda System.Web-kort under inkrementell migrering.
Välj migreringsmetod
Du har två huvudsakliga alternativ för att migrera HttpContext från ASP.NET Framework till ASP.NET Core. Ditt val beror på din tidslinje för migrering, om du behöver köra båda programmen samtidigt och hur mycket kod du är villig att skriva om.
Snabb beslutsguide
Besvara dessa frågor för att välja din metod:
Gör du en fullständig omskrivning eller inkrementell migrering?
- Slutför omskrivningen → Slutför omskrivningen till ASP.NET Core HttpContext
- Inkrementell migrering → Fortsätt till fråga 2
Har du omfattande HttpContext-användning i delade bibliotek?
- Ja, massor av delad kod → System.Web-adaptrar
- Nej, isolerad HttpContext-användning → Fullständig omskrivning till ASP.NET Core HttpContext
Jämförelse av migreringstillvägagångssätt
| Tillvägagångssätt | Kodändringar | Prestanda | Delade bibliotek | När du ska använda |
|---|---|---|---|---|
| Fullständig omskrivning | Hög – Skriv om all HttpContext-kod | Bäst | Kräver uppdateringar | Slutför omskrivningar, prestandakritiska appar |
| System.Web-adaptrar | Låg – Behåll befintliga mönster | Bra | Fungerar med befintlig kod | Inkrementella migreringar, omfattande HttpContext-användning |
Viktiga skillnader
HttpContext-livslängd
Adaptrarna stöds av HttpContext som inte kan användas efter livet av en begäran. HttpContext När den körs på ASP.NET Core kan därför inte även användas efter en begäran, medan den i ASP.NET Framework skulle fungera ibland. En ObjectDisposedException utlöses i de fall där den används efter att en begäran har avslutats.
Rekommendation: Lagra de värden som behövs i en POCO och håll fast vid det.
Be om trådöverväganden
Varning
ASP.NET Core garanterar inte trådtillhörighet för begäranden. Om koden kräver trådsäker åtkomst till HttpContextmåste du säkerställa korrekt synkronisering.
I ASP.NET Framework hade en begäran trådtillhörighet och Current skulle endast vara tillgänglig om den finns i den tråden. ASP.NET Core har inte den här garantin så Current kommer att vara tillgänglig inom samma asynkrona kontext, men inga garantier för trådar görs.
Rekommendation: Om du läser/skriver till HttpContext måste du se till att du gör det på ett enskilt trådat sätt. Du kan tvinga en begäran att aldrig köras samtidigt i någon asynkron kontext genom att ange ISingleThreadedRequestMetadata. Detta får prestandakonsekvenser och bör endast användas om du inte kan omstrukturera användningen för att säkerställa icke-samtidig åtkomst. Det finns en implementering tillgänglig att lägga till för styrenheter med SingleThreadedRequestAttribute:
[SingleThreadedRequest]
public class SomeController : Controller
{
...
}
Begär strömbuffertning
Som standard är den inkommande begäran inte alltid sökbar eller helt tillgänglig. För att uppnå det beteende som finns i .NET Framework kan du välja att förbuffra indataströmmen. Detta läser den inkommande strömmen fullständigt och buffras till minne eller disk (beroende på inställningar).
Rekommendation: Detta kan aktiveras genom att använda slutpunktsmetadata som implementerar IPreBufferRequestStreamMetadata gränssnittet. Detta är tillgängligt som ett attribut PreBufferRequestStreamAttribute som kan tillämpas på kontrollanter eller metoder.
För att aktivera detta på alla MVC-slutpunkter finns det en tilläggsmetod som kan användas på följande sätt:
app.MapDefaultControllerRoute()
.PreBufferRequestStream();
Buffring av svarsström
Vissa API:er på Response kräver att utdataströmmen buffrats, till exempel Output, End(), Clear()och SuppressContent.
Rekommendation: För att stöda beteende för Response detta kräver buffring av svaret innan det skickas, måste slutpunkter välja det med slutpunktsmetadata som implementerar IBufferResponseStreamMetadata.
För att aktivera detta på alla MVC-slutpunkter finns det en tilläggsmetod som kan användas på följande sätt:
app.MapDefaultControllerRoute()
.BufferResponseStream();
Slutför omskrivningen till ASP.NET Core HttpContext
Välj den här metoden när du utför en fullständig migrering och kan skriva om HttpContext-relaterad kod för att använda ASP.NET Cores interna implementering.
ASP.NET Cores HttpContext ger en mer modulär och utökningsbar design jämfört med ASP.NET Framework. Den här metoden ger bästa prestanda men kräver fler kodändringar under migreringen.
Översikt
HttpContext har ändrats avsevärt i ASP.NET Core. När du migrerar HTTP-moduler eller hanterare till mellanprogram måste du uppdatera koden så att den fungerar med det nya HttpContext API:et.
I ASP.NET Core-mellanprogram Invoke tar metoden en parameter av typen HttpContext:
public async Task Invoke(HttpContext context)
Detta HttpContext skiljer sig från ASP.NET Framework-versionen och kräver olika metoder för åtkomst till information om begäranden och svar.
Egenskapsöversättningar
Det här avsnittet visar hur du översätter de vanligaste egenskaperna System.Web.HttpContext för till motsvarande Microsoft.AspNetCore.Http.HttpContext i ASP.NET Core.
HttpContext-egenskaper
HttpContext.Items → HttpContext.Items
IDictionary<object, object> items = httpContext.Items;Ingen motsvarande → HttpContext.TraceIdentifier
string requestId = httpContext.TraceIdentifier;Unikt begärande-ID för loggning
HttpRequest-egenskaper
HttpRequest.HttpMethod → HttpRequest.Method
string httpMethod = httpContext.Request.Method;HttpRequest.QueryString → HttpRequest.QueryString
IQueryCollection queryParameters = httpContext.Request.Query; // If no query parameter "key" used, values will have 0 items // If single value used for a key (...?key=v1), values will have 1 item ("v1") // If key has multiple values (...?key=v1&key=v2), values will have 2 items ("v1" and "v2") IList<string> values = queryParameters["key"]; // If no query parameter "key" used, value will be "" // If single value used for a key (...?key=v1), value will be "v1" // If key has multiple values (...?key=v1&key=v2), value will be "v1,v2" string value = queryParameters["key"].ToString();HttpRequest.Url / HttpRequest.RawUrl → Flera egenskaper
// using Microsoft.AspNetCore.Http.Extensions; var url = httpContext.Request.GetDisplayUrl();Använd Request.Scheme, Host, PathBase, Path, QueryString
HttpRequest.IsSecureConnection → HttpRequest.IsHttps
var isSecureConnection = httpContext.Request.IsHttps;HttpRequest.UserHostAddress → ConnectionInfo.RemoteIpAddress
var userHostAddress = httpContext.Connection.RemoteIpAddress?.ToString();HttpRequest.Cookies → HttpRequest.Cookies
IRequestCookieCollection cookies = httpContext.Request.Cookies; string unknownCookieValue = cookies["unknownCookie"]; // will be null (no exception) string knownCookieValue = cookies["cookie1name"]; // will be actual valueHttpRequest.RequestContext → RoutingHttpContextExtensions.GetRouteData
var routeValue = httpContext.GetRouteValue("key");HttpRequest.Headers → HttpRequest.Headers
// using Microsoft.AspNetCore.Http.Headers; // using Microsoft.Net.Http.Headers; IHeaderDictionary headersDictionary = httpContext.Request.Headers; // GetTypedHeaders extension method provides strongly typed access to many headers var requestHeaders = httpContext.Request.GetTypedHeaders(); CacheControlHeaderValue cacheControlHeaderValue = requestHeaders.CacheControl; // For unknown header, unknownheaderValues has zero items and unknownheaderValue is "" IList<string> unknownheaderValues = headersDictionary["unknownheader"]; string unknownheaderValue = headersDictionary["unknownheader"].ToString(); // For known header, knownheaderValues has 1 item and knownheaderValue is the value IList<string> knownheaderValues = headersDictionary[HeaderNames.AcceptLanguage]; string knownheaderValue = headersDictionary[HeaderNames.AcceptLanguage].ToString();HttpRequest.UserAgent → HttpRequest.Headers
string userAgent = headersDictionary[HeaderNames.UserAgent].ToString();HttpRequest.UrlReferrer → HttpRequest.Headers
string urlReferrer = headersDictionary[HeaderNames.Referer].ToString();HttpRequest.ContentType → HttpRequest.ContentType
// using Microsoft.Net.Http.Headers; MediaTypeHeaderValue mediaHeaderValue = requestHeaders.ContentType; string contentType = mediaHeaderValue?.MediaType.ToString(); // ex. application/x-www-form-urlencoded string contentMainType = mediaHeaderValue?.Type.ToString(); // ex. application string contentSubType = mediaHeaderValue?.SubType.ToString(); // ex. x-www-form-urlencoded System.Text.Encoding requestEncoding = mediaHeaderValue?.Encoding;HttpRequest.Form → HttpRequest.Form
if (httpContext.Request.HasFormContentType) { IFormCollection form; form = httpContext.Request.Form; // sync // Or form = await httpContext.Request.ReadFormAsync(); // async string firstName = form["firstname"]; string lastName = form["lastname"]; }Varning: Läs formulärvärden endast om innehållstypen är x-www-form-urlencoded eller form-data
HttpRequest.InputStream → HttpRequest.Body
string inputBody; using (var reader = new System.IO.StreamReader( httpContext.Request.Body, System.Text.Encoding.UTF8)) { inputBody = reader.ReadToEnd(); }Varning: Använd endast i mellanprogram för hanterare i slutet av pipelinen. Body kan bara läsas en gång per anrop
HttpResponse-egenskaper
HttpResponse.Status / HttpResponse.StatusDescription → HttpResponse.StatusCode
// using Microsoft.AspNetCore.Http; httpContext.Response.StatusCode = StatusCodes.Status200OK;HttpResponse.ContentEncoding / HttpResponse.ContentType → HttpResponse.ContentType
// using Microsoft.Net.Http.Headers; var mediaType = new MediaTypeHeaderValue("application/json"); mediaType.Encoding = System.Text.Encoding.UTF8; httpContext.Response.ContentType = mediaType.ToString();HttpResponse.ContentType → HttpResponse.ContentType
httpContext.Response.ContentType = "text/html";HttpResponse.Output → HttpResponseWritingExtensions.WriteAsync
string responseContent = GetResponseContent(); await httpContext.Response.WriteAsync(responseContent);HttpResponse.TransmitFile → Se förfrågningsfunktioner
Serveringsfiler beskrivs i begärandefunktioner i ASP.NET Core
HttpResponse.Headers → HttpResponse.OnStarting
// using Microsoft.AspNet.Http.Headers; // using Microsoft.Net.Http.Headers; private Task SetHeaders(object context) { var httpContext = (HttpContext)context; // Set header with single value httpContext.Response.Headers["ResponseHeaderName"] = "headerValue"; // Set header with multiple values string[] responseHeaderValues = new string[] { "headerValue1", "headerValue1" }; httpContext.Response.Headers["ResponseHeaderName"] = responseHeaderValues; // Translating ASP.NET 4's HttpContext.Response.RedirectLocation httpContext.Response.Headers[HeaderNames.Location] = "http://www.example.com"; // Or httpContext.Response.Redirect("http://www.example.com"); // GetTypedHeaders extension method provides strongly typed access to many headers var responseHeaders = httpContext.Response.GetTypedHeaders(); // Translating ASP.NET 4's HttpContext.Response.CacheControl responseHeaders.CacheControl = new CacheControlHeaderValue { MaxAge = new System.TimeSpan(365, 0, 0, 0) // Many more properties available }; // If you use .NET Framework 4.6+, Task.CompletedTask will be a bit faster return Task.FromResult(0); }Måste använda callback-mönster för att ange huvuden innan svaret startar
HttpResponse.Cookies → HttpResponse.OnStarting
private Task SetCookies(object context) { var httpContext = (HttpContext)context; IResponseCookies responseCookies = httpContext.Response.Cookies; responseCookies.Append("cookie1name", "cookie1value"); responseCookies.Append("cookie2name", "cookie2value", new CookieOptions { Expires = System.DateTime.Now.AddDays(5), HttpOnly = true }); // If you use .NET Framework 4.6+, Task.CompletedTask will be a bit faster return Task.FromResult(0); }Måste använda återanropsmönster för att ange cookies innan svaret startar
Ange svarshuvuden:
public async Task Invoke(HttpContext httpContext) { // Set callback to execute before response starts httpContext.Response.OnStarting(SetHeaders, state: httpContext); // ... rest of middleware logic }Ange svarscookies:
public async Task Invoke(HttpContext httpContext)
{
// Set callbacks to execute before response starts
httpContext.Response.OnStarting(SetCookies, state: httpContext);
httpContext.Response.OnStarting(SetHeaders, state: httpContext);
// ... rest of middleware logic
}
System.Web-adaptrar
Anmärkning
På så sätt används System.Web Adapters för att förenkla migreringen.
Välj den här metoden när du har omfattande HttpContext-användning i delade bibliotek eller när du utför en inkrementell migrering där du vill minimera kodändringar.
System.Web-adaptrar tillhandahåller ett kompatibilitetslager som gör att du kan använda bekanta HttpContext API:er i ASP.NET Core-program. Den här metoden är särskilt användbar när:
- Du har gemensamma bibliotek som använder HttpContext
- Du utför en inkrementell migrering
- Du vill minimera kodändringar under migreringsprocessen
Fördelar med att använda System.Web-adaptrar
-
Minimala kodändringar: Behåll dina befintliga
System.Web.HttpContextanvändningsmönster - Delade bibliotek: Bibliotek kan fungera med både ASP.NET Framework och ASP.NET Core
- Inkrementell migrering: Migrera program bit för bit utan att bryta delade beroenden
- Snabbare migrering: Minska den tid som krävs för att migrera komplexa program
Överväganden
- Prestanda: Även om de är bra medför adaptrar viss overhead jämfört med inbyggda ASP.NET Core-API:er
- Funktionsparitet: Inte alla funktioner är tillgängliga via HttpContext adaptrar
- Långsiktig strategi: Överväg att så småningom migrera till interna ASP.NET Core-API:er för bästa prestanda
Mer information om System.Web-kort finns i dokumentationen om System.Web-kort.
Ytterligare resurser
ASP.NET Core