migrace obslužných rutin a modulů HTTP do ASP.NET Core middlewaru

tento článek ukazuje, jak migrovat existující ASP.NET moduly HTTP a obslužné rutiny ze serveru system. webserver do ASP.NET Core middlewaru.

Přenavštívené moduly a obslužné rutiny

než začnete ASP.NET Core middlewaru, nejdřív si rekapitulace, jak fungují moduly HTTP a obslužné rutiny:

Obslužná rutina modulů

Obslužné rutiny:

  • Třídy, které implementují IHttpHandler

  • Slouží ke zpracování požadavků s daným názvem nebo příponou souboru, například . Report.

  • Nakonfigurováno v Web.config

Moduly jsou:

  • Třídy, které implementují IHttpModule

  • Vyvoláno pro každý požadavek

  • Schopnost krátkodobého okruhu (zastavení dalšího zpracování žádosti)

  • Může přidat do odpovědi HTTP nebo vytvořit vlastní.

  • Nakonfigurováno v Web.config

Pořadí, ve kterém moduly zpracovávají příchozí požadavky, určuje:

  1. události řady, které jsou aktivovány ASP.NET, například BeginRequest a AuthenticateRequest . Úplný seznam najdete v tématu System.Web.HttpApplication . Každý modul může vytvořit obslužnou rutinu pro jednu nebo více událostí.

  2. Pro stejnou událost, pořadí, ve kterém jsou nakonfigurované v Web.config.

Kromě modulů můžete přidat obslužné rutiny pro události životního cyklu do souboru Global. asax. cs . Tyto obslužné rutiny jsou spouštěny po obslužných rutinách v konfigurovaných modulech.

Z obslužných rutin a modulů pro middleware

Middleware jsou jednodušší než moduly HTTP a obslužné rutiny:

  • Moduly, obslužné rutiny, Global. asax. cs, Web.config (s výjimkou konfigurace služby IIS) a životní cyklus aplikace se odešlou.

  • Služba middlewaru převzala role obou modulů i obslužných rutin.

  • Middleware jsou nakonfigurovány pomocí kódu, nikoli v Web.config

  • Větvení kanálu vám umožňuje odesílat požadavky na konkrétní middleware na základě nejen adresy URL, ale také na hlavičkách žádostí, řetězcích dotazů atd.
  • Větvení kanálu vám umožňuje odesílat požadavky na konkrétní middleware na základě nejen adresy URL, ale také na hlavičkách žádostí, řetězcích dotazů atd.

Middleware jsou velmi podobné modulům:

  • Vyvoláno v principu pro každý požadavek

  • Může se stát, že žádost nebude v krátkém okruhu předávat do dalšího middlewaru .

  • Schopné vytvořit vlastní odpověď HTTP

Middleware a moduly jsou zpracovávány v jiném pořadí:

Middleware autorizace – krátké okruhy: žádost pro uživatele, který není autorizovaný. Požadavek na stránku indexu je povolen a zpracován middlewarem MVC. Požadavek na sestavu prodeje je povolen a zpracován vlastním middlewarem sestavy.

Všimněte si, jak je výše uvedený obrázek, ověřovací middleware krátce vyřídil požadavek.

Migrace kódu modulu do middlewaru

Existující modul HTTP bude vypadat nějak takto:

// ASP.NET 4 module

using System;
using System.Web;

namespace MyApp.Modules
{
    public class MyModule : IHttpModule
    {
        public void Dispose()
        {
        }

        public void Init(HttpApplication application)
        {
            application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
            application.EndRequest += (new EventHandler(this.Application_EndRequest));
        }

        private void Application_BeginRequest(Object source, EventArgs e)
        {
            HttpContext context = ((HttpApplication)source).Context;

            // Do something with context near the beginning of request processing.
        }

        private void Application_EndRequest(Object source, EventArgs e)
        {
            HttpContext context = ((HttpApplication)source).Context;

            // Do something with context near the end of request processing.
        }
    }
}

jak je znázorněno na stránce middleware , ASP.NET Core middleware je třída, která zpřístupňuje Invoke metodu s HttpContext návratem a Task . Váš nový middleware bude vypadat takto:

// ASP.NET Core middleware

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;

namespace MyApp.Middleware
{
    public class MyMiddleware
    {
        private readonly RequestDelegate _next;

        public MyMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            // Do something with context near the beginning of request processing.

            await _next.Invoke(context);

            // Clean up.
        }
    }

    public static class MyMiddlewareExtensions
    {
        public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<MyMiddleware>();
        }
    }
}

Předchozí šablona middlewaru byla pořízena z oddílu o zápisu middlewaru.

Pomocná třída MyMiddlewareExtensions usnadňuje konfiguraci middlewaru ve vaší Startup třídě. UseMyMiddlewareMetoda přidá třídu middleware do kanálu požadavků. Služby, které vyžaduje middleware, se vloží do konstruktoru middlewaru.

Váš modul může ukončit žádost, například pokud uživatel není autorizovaný:

// ASP.NET 4 module that may terminate the request

private void Application_BeginRequest(Object source, EventArgs e)
{
    HttpContext context = ((HttpApplication)source).Context;

    // Do something with context near the beginning of request processing.

    if (TerminateRequest())
    {
        context.Response.End();
        return;
    }
}

Middleware to zpracovává tím, že nevolá Invoke na další middleware v kanálu. Mějte na paměti, že to neukončí celý požadavek, protože předchozí middleware budou přesto vyvolány, když odpověď prochází způsobem kanálu.

// ASP.NET Core middleware that may terminate the request

public async Task Invoke(HttpContext context)
{
    // Do something with context near the beginning of request processing.

    if (!TerminateRequest())
        await _next.Invoke(context);

    // Clean up.
}

Když migrujete funkci modulu na nový middleware, může se stát, že váš kód nebude zkompilován, protože se HttpContext v ASP.NET Core významně změnila třída. pozdějise dozvíte, jak migrovat do nové ASP.NET Core HttpContext.

Migruje se vložení modulu do kanálu požadavků.

Moduly HTTP se obvykle přidávají do kanálu požadavků pomocí Web.config:

<?xml version="1.0" encoding="utf-8"?>
<!--ASP.NET 4 web.config-->
<configuration>
  <system.webServer>
    <modules>
      <add name="MyModule" type="MyApp.Modules.MyModule"/>
    </modules>
  </system.webServer>
</configuration>

Převeďte to přidáním nového middlewaru do kanálu požadavků ve vaší Startup třídě:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseMyMiddleware();

    app.UseMyMiddlewareWithParams();

    var myMiddlewareOptions = Configuration.GetSection("MyMiddlewareOptionsSection").Get<MyMiddlewareOptions>();
    var myMiddlewareOptions2 = Configuration.GetSection("MyMiddlewareOptionsSection2").Get<MyMiddlewareOptions>();
    app.UseMyMiddlewareWithParams(myMiddlewareOptions);
    app.UseMyMiddlewareWithParams(myMiddlewareOptions2);

    app.UseMyTerminatingMiddleware();

    // Create branch to the MyHandlerMiddleware. 
    // All requests ending in .report will follow this branch.
    app.MapWhen(
        context => context.Request.Path.ToString().EndsWith(".report"),
        appBranch => {
            // ... optionally add more middleware to this branch
            appBranch.UseMyHandler();
        });

    app.MapWhen(
        context => context.Request.Path.ToString().EndsWith(".context"),
        appBranch => {
            appBranch.UseHttpContextDemoMiddleware();
        });

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

Přesné místo v kanálu, kam vložíte nový middleware, závisí na události, kterou zpracuje jako modul ( BeginRequest , EndRequest atd.) a pořadí v seznamu modulů v Web.config.

jak je uvedeno výše, v ASP.NET Core není žádný životní cyklus aplikace a pořadí, ve kterém jsou odpovědi zpracovávány middlewarem, se liší od pořadí používaného moduly. To může být náročnější na rozhodnutí o řazení.

Pokud se řazení stalo problémem, mohli byste svůj modul rozdělit do několika součástí middlewaru, které je možné seřadit nezávisle.

Migrace kódu obslužné rutiny do middlewaru

Obslužná rutina HTTP vypadá nějak takto:

// ASP.NET 4 handler

using System.Web;

namespace MyApp.HttpHandlers
{
    public class MyHandler : IHttpHandler
    {
        public bool IsReusable { get { return true; } }

        public void ProcessRequest(HttpContext context)
        {
            string response = GenerateResponse(context);

            context.Response.ContentType = GetContentType();
            context.Response.Output.Write(response);
        }

        // ...

        private string GenerateResponse(HttpContext context)
        {
            string title = context.Request.QueryString["title"];
            return string.Format("Title of the report: {0}", title);
        }

        private string GetContentType()
        {
            return "text/plain";
        }
    }
}

v projektu ASP.NET Core byste ho přeložili na middleware podobnou této:

// ASP.NET Core middleware migrated from a handler

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;

namespace MyApp.Middleware
{
    public class MyHandlerMiddleware
    {

        // Must have constructor with this signature, otherwise exception at run time
        public MyHandlerMiddleware(RequestDelegate next)
        {
            // This is an HTTP Handler, so no need to store next
        }

        public async Task Invoke(HttpContext context)
        {
            string response = GenerateResponse(context);

            context.Response.ContentType = GetContentType();
            await context.Response.WriteAsync(response);
        }

        // ...

        private string GenerateResponse(HttpContext context)
        {
            string title = context.Request.Query["title"];
            return string.Format("Title of the report: {0}", title);
        }

        private string GetContentType()
        {
            return "text/plain";
        }
    }

    public static class MyHandlerExtensions
    {
        public static IApplicationBuilder UseMyHandler(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<MyHandlerMiddleware>();
        }
    }
}

Tento middleware je velmi podobný middlewaru, který odpovídá modulům. Jediným skutečným rozdílem je, že zde není žádné volání _next.Invoke(context) . To dává smysl, protože obslužná rutina je na konci kanálu požadavků, takže nebudete moct vyvolat žádné další middleware.

Migrace vložení obslužné rutiny do kanálu žádosti

Konfigurace obslužné rutiny HTTP se provádí v Web.config a vypadá nějak takto:

<?xml version="1.0" encoding="utf-8"?>
<!--ASP.NET 4 web.config-->
<configuration>
  <system.webServer>
    <handlers>
      <add name="MyHandler" verb="*" path="*.report" type="MyApp.HttpHandlers.MyHandler" resourceType="Unspecified" preCondition="integratedMode"/>
    </handlers>
  </system.webServer>
</configuration>

To můžete převést přidáním nového middlewaru obslužné rutiny do kanálu požadavků ve vaší Startup třídě, podobně jako middleware převedené z modulů. Problém s tímto přístupem je, že by poslal všechny žádosti do nového middlewaru obslužné rutiny. Nicméně budete chtít, aby žádosti s daným rozšířením dosáhly vašeho middlewaru. To vám poskytne stejné funkce jako u vaší obslužné rutiny HTTP.

Jedním z řešení je vytvořit větev kanálu pro žádosti s danou příponou pomocí MapWhen metody rozšíření. Provedete to stejným způsobem, jakým Configure přidáte další middleware:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseMyMiddleware();

    app.UseMyMiddlewareWithParams();

    var myMiddlewareOptions = Configuration.GetSection("MyMiddlewareOptionsSection").Get<MyMiddlewareOptions>();
    var myMiddlewareOptions2 = Configuration.GetSection("MyMiddlewareOptionsSection2").Get<MyMiddlewareOptions>();
    app.UseMyMiddlewareWithParams(myMiddlewareOptions);
    app.UseMyMiddlewareWithParams(myMiddlewareOptions2);

    app.UseMyTerminatingMiddleware();

    // Create branch to the MyHandlerMiddleware. 
    // All requests ending in .report will follow this branch.
    app.MapWhen(
        context => context.Request.Path.ToString().EndsWith(".report"),
        appBranch => {
            // ... optionally add more middleware to this branch
            appBranch.UseMyHandler();
        });

    app.MapWhen(
        context => context.Request.Path.ToString().EndsWith(".context"),
        appBranch => {
            appBranch.UseHttpContextDemoMiddleware();
        });

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

MapWhen přebírá tyto parametry:

  1. Výraz lambda, který přebírá HttpContext a vrátí, true zda by požadavek měl přejít mimo větev. To znamená, že můžete požadavky větví nejenom na základě jejich rozšíření, ale také v hlavičkách žádostí, parametrech řetězce dotazu atd.

  2. Lambda, který přebírá IApplicationBuilder a přidává všechny middleware pro větev. To znamená, že můžete přidat další middleware do větve před middlewarem vaší obslužné rutiny.

Middleware přidaný do kanálu před tím, než se větev vyvolá u všech požadavků; Tato větev nebude mít žádný vliv.

Načítání možností middlewaru pomocí vzoru možností

Některé moduly a obslužné rutiny mají možnosti konfigurace, které jsou uloženy v Web.config. v ASP.NET Core se ale místo Web.config používá nový model konfigurace.

Nový konfigurační systém poskytuje tyto možnosti, jak tento problém vyřešit:

  1. Vytvořte třídu pro uložení vašich možností middlewaru, například:

    public class MyMiddlewareOptions
    {
        public string Param1 { get; set; }
        public string Param2 { get; set; }
    }
    
  2. Uložení hodnot možností

    Konfigurační systém umožňuje ukládat hodnoty možností kdekoli, kde chcete. Většina lokalit ale používá appsettings.json , takže povedeme tento přístup:

    {
      "MyMiddlewareOptionsSection": {
        "Param1": "Param1Value",
        "Param2": "Param2Value"
      }
    }
    

    MyMiddlewareOptionsSection je tady název oddílu. Nemusí být stejný jako název vaší třídy možností.

  3. Přidružit hodnoty možnosti k třídě Options

    vzor možností používá ASP.NET Core rozhraní pro vkládání závislostí k přidružení typu možností (například) k MyMiddlewareOptions MyMiddlewareOptions objektu, který má skutečné možnosti.

    Aktualizujte svou Startup třídu:

    1. Pokud používáte appsettings.json , přidejte ho do Tvůrce konfigurace v Startup konstruktoru:

      public Startup(IHostingEnvironment env)
      {
          var builder = new ConfigurationBuilder()
              .SetBasePath(env.ContentRootPath)
              .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
              .AddEnvironmentVariables();
          Configuration = builder.Build();
      }
      
    2. Nakonfigurujte službu možností:

      public void ConfigureServices(IServiceCollection services)
      {
          // Setup options service
          services.AddOptions();
      
          // Load options from section "MyMiddlewareOptionsSection"
          services.Configure<MyMiddlewareOptions>(
              Configuration.GetSection("MyMiddlewareOptionsSection"));
      
          // Add framework services.
          services.AddMvc();
      }
      
    3. Přidružte možnosti k vaší třídě možností:

      public void ConfigureServices(IServiceCollection services)
      {
          // Setup options service
          services.AddOptions();
      
          // Load options from section "MyMiddlewareOptionsSection"
          services.Configure<MyMiddlewareOptions>(
              Configuration.GetSection("MyMiddlewareOptionsSection"));
      
          // Add framework services.
          services.AddMvc();
      }
      
  4. Vloží možnosti do konstruktoru middlewaru. To je podobné jako vkládání možností do kontroleru.

    public class MyMiddlewareWithParams
    {
        private readonly RequestDelegate _next;
        private readonly MyMiddlewareOptions _myMiddlewareOptions;
    
        public MyMiddlewareWithParams(RequestDelegate next,
            IOptions<MyMiddlewareOptions> optionsAccessor)
        {
            _next = next;
            _myMiddlewareOptions = optionsAccessor.Value;
        }
    
        public async Task Invoke(HttpContext context)
        {
            // Do something with context near the beginning of request processing
            // using configuration in _myMiddlewareOptions
    
            await _next.Invoke(context);
    
            // Do something with context near the end of request processing
            // using configuration in _myMiddlewareOptions
        }
    }
    

    Rozšiřující metoda UseMiddleware , která přidává váš middleware, se IApplicationBuilder stará o vkládání závislostí.

    To není omezeno na IOptions objekty. Jakýkoli jiný objekt, který váš middleware vyžaduje, může být tímto způsobem vložen.

Načítání možností middlewaru prostřednictvím přímého vkládání

Vzor možností má výhodu, že vytvoří volné propojení mezi hodnotami možností a jejich příjemci. Po přidružení třídy možností se skutečnými hodnotami možností může jakákoliv jiná třída získat přístup k možnostem prostřednictvím rozhraní injektáže pro vkládání závislostí. Nemusíte předávat hodnoty možností.

Tato možnost se ukončí, pokud chcete stejný middleware používat dvakrát a s různými možnostmi. Například autorizační middleware používaný v různých větvích umožňuje různé role. Nelze přidružit dva různé objekty možností s jednou třídou možností.

Řešením je získat objekty možností se skutečnými hodnotami možností ve vaší Startup třídě a předat je přímo do každé instance vašeho middlewaru.

  1. Přidat druhý klíč do appsettings.json

    Pro přidání druhé sady možností do appsettings.json souboru použijte nový klíč k jeho jedinečné identifikaci:

    {
      "MyMiddlewareOptionsSection2": {
        "Param1": "Param1Value2",
        "Param2": "Param2Value2"
      },
      "MyMiddlewareOptionsSection": {
        "Param1": "Param1Value",
        "Param2": "Param2Value"
      }
    }
    
  2. Načtěte hodnoty možností a předejte je middlewaru. Use...Metoda rozšíření (která přidá váš middleware do kanálu) je logické místo, které se má předat v hodnotách možností:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
    
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }
    
        app.UseMyMiddleware();
    
        app.UseMyMiddlewareWithParams();
    
        var myMiddlewareOptions = Configuration.GetSection("MyMiddlewareOptionsSection").Get<MyMiddlewareOptions>();
        var myMiddlewareOptions2 = Configuration.GetSection("MyMiddlewareOptionsSection2").Get<MyMiddlewareOptions>();
        app.UseMyMiddlewareWithParams(myMiddlewareOptions);
        app.UseMyMiddlewareWithParams(myMiddlewareOptions2);
    
        app.UseMyTerminatingMiddleware();
    
        // Create branch to the MyHandlerMiddleware. 
        // All requests ending in .report will follow this branch.
        app.MapWhen(
            context => context.Request.Path.ToString().EndsWith(".report"),
            appBranch => {
                // ... optionally add more middleware to this branch
                appBranch.UseMyHandler();
            });
    
        app.MapWhen(
            context => context.Request.Path.ToString().EndsWith(".context"),
            appBranch => {
                appBranch.UseHttpContextDemoMiddleware();
            });
    
        app.UseStaticFiles();
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
    
  3. Povolte middlewari, aby převzala parametr options. Poskytněte přetížení Use... metody rozšíření (která převezme parametr options a předá ho do UseMiddleware ). Když UseMiddleware je volána s parametry, předá parametry konstruktoru middleware při vytváření instance objektu middleware.

    public static class MyMiddlewareWithParamsExtensions
    {
        public static IApplicationBuilder UseMyMiddlewareWithParams(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<MyMiddlewareWithParams>();
        }
    
        public static IApplicationBuilder UseMyMiddlewareWithParams(
            this IApplicationBuilder builder, MyMiddlewareOptions myMiddlewareOptions)
        {
            return builder.UseMiddleware<MyMiddlewareWithParams>(
                new OptionsWrapper<MyMiddlewareOptions>(myMiddlewareOptions));
        }
    }
    

    Všimněte si, jak toto zabalí objekt Options v OptionsWrapper objektu. To implementuje IOptions , podle očekávání konstruktoru middlewaru.

Migrace na novou HttpContext

Dříve jste viděli, že Invoke metoda v middlewaru přebírá parametr typu HttpContext :

public async Task Invoke(HttpContext context)

HttpContextvýznamně se změnil v ASP.NET Core. V této části se dozvíte, jak přeložit nejčastěji používané vlastnosti System. Web. HttpContext na nový Microsoft.AspNetCore.Http.HttpContext .

HttpContext

HttpContext. Items se přeloží:

IDictionary<object, object> items = httpContext.Items;

Jedinečné ID žádosti (žádný System. Web. HttpContext protějšek)

Poskytuje jedinečné ID pro každý požadavek. Je velmi užitečné zahrnout do protokolů.

string requestId = httpContext.TraceIdentifier;

HttpContext. Request

HttpContext. Request. HttpMethod se překládá na:

string httpMethod = httpContext.Request.Method;

HttpContext. Request. QueryString se překládá na:

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();

HttpContext. Request. URL a HttpContext. Request. RawUrl přeložit na:

// using Microsoft.AspNetCore.Http.Extensions;
var url = httpContext.Request.GetDisplayUrl();

HttpContext. Request. IsSecureConnection se překládá na:

var isSecureConnection = httpContext.Request.IsHttps;

HttpContext. Request. UserHostAddress se překládá na:

var userHostAddress = httpContext.Connection.RemoteIpAddress?.ToString();

HttpContext. Request. Cookie s se překládá na:

IRequestCookieCollection cookies = httpContext.Request.Cookies;
string unknownCookieValue = cookies["unknownCookie"]; // will be null (no exception)
string knownCookieValue = cookies["cookie1name"];     // will be actual value

HttpContext. Request. Třída requestContext. parametr RouteData se překládá na:

var routeValue = httpContext.GetRouteValue("key");

HttpContext. Request. Headers transformuje:

// 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();

HttpContext. Request. UserAgent se převádí na:

string userAgent = headersDictionary[HeaderNames.UserAgent].ToString();

HttpContext. Request. UrlReferrer se překládá na:

string urlReferrer = headersDictionary[HeaderNames.Referer].ToString();

HttpContext. Request. ContentType se překládá na:

// 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;

HttpContext. Request. Form se překládá na:

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í

Přečte hodnoty formuláře pouze v případě, že je podřízený typ obsahu x-www-form-urlencoded nebo form-data.

HttpContext. Request. InputStream se překládá na:

string inputBody;
using (var reader = new System.IO.StreamReader(
    httpContext.Request.Body, System.Text.Encoding.UTF8))
{
    inputBody = reader.ReadToEnd();
}

Upozornění

Tento kód používejte pouze v middlewari typu pro zpracování, na konci kanálu.

Nezpracovaný text si můžete přečíst, jak je znázorněno výše na vyžádání. Middleware, který se pokouší přečíst tělo po prvním čtení, načte prázdné tělo.

To se nevztahuje na čtení formuláře uvedeného výše, protože to je hotové z vyrovnávací paměti.

HttpContext. Response

HttpContext. Response. status a HttpContext. Response. StatusDescription přeložit na:

// using Microsoft.AspNetCore.Http;
httpContext.Response.StatusCode = StatusCodes.Status200OK;

Vlastnost HttpContext. Response. ContentEncoding a HttpContext. Response. ContentType se převede na:

// using Microsoft.Net.Http.Headers;
var mediaType = new MediaTypeHeaderValue("application/json");
mediaType.Encoding = System.Text.Encoding.UTF8;
httpContext.Response.ContentType = mediaType.ToString();

HttpContext. Response. ContentType sám o sobě také přeloží:

httpContext.Response.ContentType = "text/html";

HttpContext. Response. Output se překládá na:

string responseContent = GetResponseContent();
await httpContext.Response.WriteAsync(responseContent);

HttpContext. Response. zpracování funkce TransmitFile

Zpracování souboru je popsáno v tématu Žádosti o funkce v ASP.NET Core .

HttpContext. Response. Headers

Posílání hlaviček odpovědí je složité, protože pokud jste je nastavili po zapsání nějakého textu odpovědi, nebudou odeslány.

Řešením je nastavit metodu zpětného volání, která bude volána přímo před zápisem do odpovědi. To se nejlépe provede na začátku Invoke metody v middlewaru. Je to metoda zpětného volání, která nastavuje hlavičky odpovědi.

Následující kód nastaví metodu zpětného volání s názvem SetHeaders :

public async Task Invoke(HttpContext httpContext)
{
    // ...
    httpContext.Response.OnStarting(SetHeaders, state: httpContext);

SetHeadersMetoda zpětného volání by vypadala takto:

// 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);
}

HttpContext. Response. Cookie pracují

Cookies Cestujte do prohlížeče v hlavičce Set- Cookie Response. V důsledku toho odesílání cookie s vyžaduje stejné zpětné volání jako při odesílání hlaviček odpovědí:

public async Task Invoke(HttpContext httpContext)
{
    // ...
    httpContext.Response.OnStarting(SetCookies, state: httpContext);
    httpContext.Response.OnStarting(SetHeaders, state: httpContext);

SetCookiesMetoda zpětného volání by vypadala takto:

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); 
}

Další zdroje informací