在 ASP.NET Core 中存取
注意
這不是這篇文章的最新版本。 關於目前版本,請參閱 本文的 .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,請使用傳遞至 HttpContext 或 Invoke 方法的 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 傳入 Invoke 或 InvokeAsync 方法:
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。