共用方式為


在 ASP.NET Core 中存取 HttpContext

注意

這不是這篇文章的最新版本。 關於目前版本,請參閱 本文的 .NET 10 版本

警告

不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。

HttpContext 會封裝關於個別 HTTP 要求和回應的所有資訊。 收到 HTTP 要求時,會初始化 HttpContext 執行個體。 該 HttpContext 執行個體可透過中介軟體和應用程式架構來存取,例如 Web API 控制器、Razor 頁面、SignalR、gRPC 等等。

如需使用 HttpContext 搭配 HTTP 要求和回應的相關資訊,請參閱在 ASP.NET Core 中使用 HttpContext

HttpContext 頁面存取 Razor

Razor 頁面 PageModel 會公開 PageModel.HttpContext 屬性:

public class IndexModel : PageModel
{
    public void OnGet()
    {
        var message = HttpContext.Request.PathBase;

        // ...
    }
}

相同的屬性可以在對應的 Razor 頁面檢視中使用:

@page
@model IndexModel

@{
    var message = HttpContext.Request.PathBase;

    // ...
}

從 MVC 中的 HttpContext 檢視存取 Razor

MVC 模式中的 Razor 檢視會透過檢視上的 HttpContext 屬性公開 RazorPage.Context。 以下範例會在內部網路應用程式中使用 Windows 驗證,擷取目前的使用者名稱:

@{
    var username = Context.User.Identity.Name;

    // ...
}

從控制器存取 HttpContext

控制器會公開 ControllerBase.HttpContext 屬性:

public class HomeController : Controller
{
    public IActionResult About()
    {
        var pathBase = HttpContext.Request.PathBase;

        // ...

        return View();
    }
}

從最小 API 存取 HttpContext

若要從最小 API 使用 HttpContext,請新增 HttpContext 參數:

app.MapGet("/", (HttpContext context) => context.Response.WriteAsync("Hello World"));

從中介軟體存取 HttpContext

若要從自訂中介軟體元件使用 HttpContext,請使用傳遞至 HttpContextInvoke 方法的 InvokeAsync 參數:

public class MyCustomMiddleware
{
    // ...

    public async Task InvokeAsync(HttpContext context)
    {
        // ...
    }
}

HttpContext 存取 SignalR

若要從 HttpContext 使用 SignalR,請在 GetHttpContext 上呼叫 Hub.Context 方法:

public class MyHub : Hub
{
    public async Task SendMessage()
    {
        var httpContext = Context.GetHttpContext();

        // ...
    }
}

從 gRPC 方法存取 HttpContext

若要從 gRPC 方法使用 HttpContext,請參閱在 gRPC 方法中解析 HttpContext

從自訂元件存取 HttpContext

對於需要存取 HttpContext 的其他架構和自訂元件,建議的方法是使用內建的相依性插入 (DI) 容器來註冊相依性。 DI 容器會將 IHttpContextAccessor 提供給在其建構函式中將其宣告為相依性的任何類別:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<IUserRepository, UserRepository>();

在以下範例中:

  • UserRepository 宣告其對 IHttpContextAccessor 的相依性。
  • 當 DI 解析相依性鏈結並建立 UserRepository 的執行個體時,將提供相依性。
public class UserRepository : IUserRepository
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public UserRepository(IHttpContextAccessor httpContextAccessor) =>
        _httpContextAccessor = httpContextAccessor;

    public void LogCurrentUser()
    {
        var username = _httpContextAccessor.HttpContext.User.Identity.Name;

        // ...
    }
}

從背景執行緒存取 HttpContext

HttpContext 不是安全執行緒。 在處理要求之外讀取或寫入 HttpContext 的屬性,可能會導致 NullReferenceException

注意

如果您的應用程式偶爾會產生 NullReferenceException 錯誤,請檢閱啟動背景處理的程式碼部分,或在要求完成之後繼續處理的部分。 尋找錯誤,例如將控制器方法定義為 async void

若要使用 HttpContext 資料安全地執行背景工作:

  • 在要求處理期間複製所需的資料。
  • 將複製的資料傳遞至背景工作。
  • 在平行工作中參考 HttpContext 資料。 啟動平行工作之前,先從內容擷取所需的資料。

若要避免不安全的程式碼,請勿將 HttpContext 傳遞至會執行背景工作的方法。 改為傳遞必要的資料。 在下列範例中,SendEmail 會呼叫 SendEmailCoreAsync 以開始傳送電子郵件。 X-Correlation-Id 標頭的值會傳遞至 SendEmailCoreAsync,而不是 HttpContext。 程式碼執行不會等候 SendEmailCoreAsync 完成:

public class EmailController : Controller
{
    public IActionResult SendEmail(string email)
    {
        var correlationId = HttpContext.Request.Headers["X-Correlation-Id"].ToString();

        _ = SendEmailCoreAsync(correlationId);

        return View();
    }

    private async Task SendEmailCoreAsync(string correlationId)
    {
        // ...
    }
}

IHttpContextAccessor 元件中的 /HttpContextRazor (Blazor)

欲了解更多資訊,請參閱 ASP.NET Core Blazor 應用程式中的 IHttpContextAccessor/HttpContext

HttpContext 會封裝關於個別 HTTP 要求和回應的所有資訊。 收到 HTTP 要求時,會初始化 HttpContext 執行個體。 該 HttpContext 執行個體可透過中介軟體和應用程式架構來存取,例如 Web API 控制器、Razor 頁面、SignalR、gRPC 等等。

如需使用 HttpContext 搭配 HTTP 要求和回應的相關資訊,請參閱在 ASP.NET Core 中使用 HttpContext

HttpContext 頁面存取 Razor

Razor 頁面 PageModel 會公開 PageModel.HttpContext 屬性:

public class IndexModel : PageModel
{
    public void OnGet()
    {
        var message = HttpContext.Request.PathBase;

        // ...
    }
}

相同的屬性可以在對應的 Razor 頁面檢視中使用:

@page
@model IndexModel

@{
    var message = HttpContext.Request.PathBase;

    // ...
}

從 MVC 中的 HttpContext 檢視存取 Razor

MVC 模式中的 Razor 檢視會透過檢視上的 HttpContext 屬性公開 RazorPage.Context。 以下範例會在內部網路應用程式中使用 Windows 驗證,擷取目前的使用者名稱:

@{
    var username = Context.User.Identity.Name;

    // ...
}

從控制器存取 HttpContext

控制器會公開 ControllerBase.HttpContext 屬性:

public class HomeController : Controller
{
    public IActionResult About()
    {
        var pathBase = HttpContext.Request.PathBase;

        // ...

        return View();
    }
}

從中介軟體存取 HttpContext

使用自訂中介軟體元件時,會將 HttpContext 傳入 InvokeInvokeAsync 方法:

public class MyCustomMiddleware
{
    public Task InvokeAsync(HttpContext context)
    {
        // ...
    }
}

從自訂元件存取 HttpContext

對於需要存取 HttpContext 的其他架構和自訂元件,建議的方法是使用內建的相依性插入 (DI) 容器來註冊相依性。 DI 容器會將 IHttpContextAccessor 提供給在其建構函式中將其宣告為相依性的任何類別:

public void ConfigureServices(IServiceCollection services)
{
     services.AddControllersWithViews();
     services.AddHttpContextAccessor();
     services.AddTransient<IUserRepository, UserRepository>();
}

在以下範例中:

  • UserRepository 宣告其對 IHttpContextAccessor 的相依性。
  • 當 DI 解析相依性鏈結並建立 UserRepository 的執行個體時,將提供相依性。
public class UserRepository : IUserRepository
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public UserRepository(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void LogCurrentUser()
    {
        var username = _httpContextAccessor.HttpContext.User.Identity.Name;
        service.LogAccessRequest(username);
    }
}

從背景執行緒存取 HttpContext

HttpContext 不是安全執行緒。 在處理要求之外讀取或寫入 HttpContext 的屬性,可能會導致 NullReferenceException

注意

如果您的應用程式偶爾會產生 NullReferenceException 錯誤,請檢閱啟動背景處理的程式碼部分,或在要求完成之後繼續處理的部分。 尋找錯誤,例如將控制器方法定義為 async void

若要使用 HttpContext 資料安全地執行背景工作:

  • 在要求處理期間複製所需的資料。
  • 將複製的資料傳遞至背景工作。
  • 在平行工作中參考 HttpContext 資料。 啟動平行工作之前,先從內容擷取所需的資料。

若要避免不安全的程式碼,請勿將 HttpContext 傳遞至會執行背景工作的方法。 改為傳遞必要的資料。 在下列範例中,會呼叫 SendEmailCore 以開始傳送電子郵件。 correlationId 會傳遞至 SendEmailCore,而不是 HttpContext。 程式碼執行不會等候 SendEmailCore 完成:

public class EmailController : Controller
{
    public IActionResult SendEmail(string email)
    {
        var correlationId = HttpContext.Request.Headers["x-correlation-id"].ToString();

        _ = SendEmailCore(correlationId);

        return View();
    }

    private async Task SendEmailCore(string correlationId)
    {
        // ...
    }
}

IHttpContextAccessor 元件中的 /HttpContextRazor (Blazor)

欲了解更多資訊,請參閱 ASP.NET Core Blazor 應用程式中的 IHttpContextAccessor/HttpContext