Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
HttpContext je základní komponenta webových aplikací, která poskytuje přístup k informacím o požadavku a odpovědi HTTP. Při migraci z architektury ASP.NET na ASP.NET Core představuje HttpContext jedinečné výzvy, protože obě architektury mají různá rozhraní API a přístupy.
Proč je migrace HttpContext složitá
ASP.NET Framework a ASP.NET Core mají v podstatě různé implementace HttpContext:
- ASP.NET Framework se používá System.Web.HttpContext s integrovanými vlastnostmi a metodami
- ASP.NET Core používá Microsoft.AspNetCore.Http.HttpContext s modulárním rozšiřitelným designem
Tyto rozdíly znamenají, že kód HttpContext nemůžete jednoduše přesunout z architektury do jádra beze změn.
Přehled strategií migrace
Během migrace máte dva hlavní přístupy pro zpracování httpContextu:
- Úplné přepsání – Přepište veškerý kód HttpContext tak, aby používal nativní implementaci HttpContext ASP.NET Core.
- System.Web Adapters – Použití adaptérů k minimalizaci změn kódu při přírůstkové migraci
U většiny aplikací poskytuje migrace na nativní httpContext ASP.NET Core nejlepší výkon a udržovatelnost. Při přírůstkové migraci mohou být větší aplikace nebo ty s rozsáhlým využitím HttpContextu přínosné díky použití adaptérů System.Web.
Volba přístupu k migraci
Máte dvě hlavní možnosti migrace HttpContext z ASP.NET Framework na ASP.NET Core. Vaše volba závisí na časové ose migrace, jestli potřebujete současně spouštět obě aplikace a kolik kódu jste ochotni přepsat.
Průvodce rychlým rozhodováním
Odpovězte na tyto otázky a zvolte svůj přístup:
Provádíte úplný přepis nebo přírůstkovou migraci?
- Dokončení přepsání → Dokončení přepsání na ASP.NET Core HttpContext
- Přírůstková migrace → Pokračovat na otázku 2
Máte rozsáhlé využití HttpContext napříč sdílenými knihovnami?
- Ano, spousta sdílených kódů → System.Web adaptéry
- Ne, izolované použití HttpContext → Kompletní přepracování na ASP.NET Core HttpContext
Porovnání přístupů k migraci
| Přístup | Změny kódu | Výkon | Sdílené knihovny | Kdy použít |
|---|---|---|---|---|
| Dokončení přepsání | Vysoká – Přepsat veškerý kód HttpContext | Nejlepší | Vyžaduje aktualizace. | Kompletní přepracování, aplikace důležité pro výkon |
| System.Web adapters | Nízká – zachování existujících vzorů | Dobré | Funguje s existujícím kódem. | Přírůstkové migrace, rozsáhlé využití HttpContext |
Důležité rozdíly
Doba života httpContext
Adaptéry jsou podporovány pomocí HttpContext, který nelze používat po dobu životnosti požadavku. Když je HttpContext spuštěn na ASP.NET Core, nelze jej použít ani po dokončení požadavku, zatímco na ASP.NET Framework může někdy fungovat. V případech, kdy je použito za koncem požadavku, bude vyvoláno ObjectDisposedException.
Doporučení: Uložte potřebné hodnoty do POCO a uchovejte je.
Požadavky na aspekty dělení na vlákna
Výstraha
ASP.NET Core nezaručuje afinitu vláken pro požadavky. Pokud váš kód vyžaduje bezpečný přístup pomocí vláken k HttpContext, musíte zajistit správnou synchronizaci.
V ASP.NET Framework má požadavek spřažení vláken a Current je k dispozici pouze na tomto vlákně. ASP.NET Core tuto záruku nemá, takže Current bude k dispozici ve stejném asynchronním kontextu, ale nebudou provedeny žádné záruky týkající se vláken.
Doporučení: Při čtení a zápisu do HttpContext je nutné zajistit, abyste to udělali jednovláknově. Můžete vynutit, aby se požadavek nikdy nespustil souběžně v žádném asynchronním kontextu nastavením ISingleThreadedRequestMetadata. To bude mít vliv na výkon a mělo by se použít jenom v případě, že nemůžete refaktorovat využití, abyste zajistili nesouběhový přístup. K dispozici je implementace pro přidání kontrolerů s SingleThreadedRequestAttribute:
[SingleThreadedRequest]
public class SomeController : Controller
{
...
}
Ukládání síťových požadavků do vyrovnávací paměti streamů
Ve výchozím nastavení není příchozí požadavek vždy vyhledatelný ani plně dostupný. Pokud chcete dosáhnout chování viditelného v rozhraní .NET Framework, můžete se přihlásit k předběžnému načtení vstupního datového proudu. Příchozí datový proud se tímto plně načte a uloží do vyrovnávací paměti nebo na disk (v závislosti na nastavení).
Doporučení: Můžete to povolit použitím metadat koncového bodu, která implementují rozhraní. To je k dispozici jako atribut PreBufferRequestStreamAttribute , který lze použít pro kontrolery nebo metody.
Pokud to chcete povolit pro všechny koncové body MVC, existuje metoda rozšíření, která se dá použít následujícím způsobem:
app.MapDefaultControllerRoute()
.PreBufferRequestStream();
Ukládání streamů odpovědí do vyrovnávací paměti
Některá rozhraní API Response vyžadují uložení výstupního datového proudu do vyrovnávací paměti, například Output, End(), Clear()a SuppressContent.
Doporučení: Aby bylo možné podporovat chování Response, které vyžaduje uložení odpovědi do vyrovnávací paměti před odesláním, musí koncové body aktivovat tuto možnost pomocí implementace metadat koncového bodu IBufferResponseStreamMetadata.
Pokud to chcete povolit pro všechny koncové body MVC, existuje metoda rozšíření, která se dá použít následujícím způsobem:
app.MapDefaultControllerRoute()
.BufferResponseStream();
Dokončení přepsání na ASP.NET Core HttpContext
Tento přístup zvolte, když provádíte úplnou migraci a můžete přepsat kód související s HttpContext tak, aby používal nativní implementaci ASP.NET Core.
ASP.NET Core HttpContext poskytuje modulární a rozšiřitelný návrh v porovnání s ASP.NET Framework. Tento přístup nabízí nejlepší výkon, ale během migrace vyžaduje více změn kódu.
Přehled
HttpContext byla výrazně změněna v ASP.NET Core. Při migraci modulů HTTP nebo obslužných rutin do middlewaru budete muset aktualizovat kód, aby fungoval s novým HttpContext rozhraním API.
V middlewaru Invoke ASP.NET Core používá metoda parametr typu HttpContext:
public async Task Invoke(HttpContext context)
To HttpContext se liší od verze ASP.NET Framework a vyžaduje různé přístupy k přístupu k informacím o žádostech a odpovědích.
Překlady vlastností
Tato část ukazuje, jak přeložit nejčastěji používané vlastnosti System.Web.HttpContext na ekvivalent Microsoft.AspNetCore.Http.HttpContext v ASP.NET Core.
Vlastnosti HttpContext
HttpContext.Items → HttpContext.Items
IDictionary<object, object> items = httpContext.Items;Žádné ekvivalentní → HttpContext.TraceIdentifier
string requestId = httpContext.TraceIdentifier;Jedinečné ID požadavku pro protokolování
Vlastnosti HttpRequest
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 → více vlastností
// using Microsoft.AspNetCore.Http.Extensions; var url = httpContext.Request.GetDisplayUrl();Použijte 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"]; }Upozornění: Čtení hodnot formuláře pouze v případě, že je typ obsahu x-www-form-urlencoded nebo 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(); }Upozornění: Používejte pouze v obslužném middlewaru na konci řetězce zpracování. Text se dá na žádost přečíst jen jednou.
Vlastnosti HttpResponse
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 → Zobrazit funkce žádostí
Obsluha souborů je popsána v tématu Funkce žádosti v 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); }Před zahájením odpovědi je nutné nastavit hlavičky pomocí vzoru zpětného volání.
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); }Před zahájením odpovědi je nutné použít vzor zpětného volání k nastavení souborů cookie.
Nastavení hlaviček odpovědi:
public async Task Invoke(HttpContext httpContext) { // Set callback to execute before response starts httpContext.Response.OnStarting(SetHeaders, state: httpContext); // ... rest of middleware logic }Nastavení souborů cookie odpovědi:
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 adaptéry
Poznámka:
Díky tomu se používají adaptéry System.Web Adapters ke zjednodušení migrace.
Tento přístup zvolte, pokud máte rozsáhlé využití HttpContext ve sdílených knihovnách nebo při provádění přírůstkové migrace, ve které chcete minimalizovat změny kódu.
Adaptéry System.Web poskytují vrstvu kompatibility, která umožňuje používat známá HttpContext rozhraní API v aplikacích ASP.NET Core. Tento přístup je užitečný zejména v těchto případech:
- Máte sdílené knihovny, které používají HttpContext
- Provádíte přírůstkovou migraci
- Chcete minimalizovat změny kódu během procesu migrace.
Výhody používání adaptérů System.Web
-
Minimální změny kódu: Zachování stávajících
System.Web.HttpContextvzorů použití - Sdílené knihovny: Knihovny můžou pracovat s rozhraním ASP.NET Framework a ASP.NET Core
- Přírůstková migrace: Migrace aplikací kusem bez přerušení sdílených závislostí
- Rychlejší migrace: Zkrácení doby potřebné k migraci složitých aplikací
Úvahy
- Výkon: I když je to dobré, adaptéry představují v porovnání s nativními rozhraními API pro ASP.NET Core určitou režii.
- Parita funkcí: Ne všechny HttpContext funkce jsou dostupné prostřednictvím adaptérů.
- Dlouhodobá strategie: Zvažte možnost nakonec migrovat na nativní rozhraní API ASP.NET Core pro zajištění nejlepšího výkonu.
Další informace o adaptérech System.Web najdete v dokumentaci k adaptérům System.Web.