次の方法で共有


ASP.NET Core の HttpContext にアクセスする

Note

これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。

警告

このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。

重要

この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。

現在のリリースについては、この記事の .NET 9 バージョンを参照してください。

HttpContext を指定すると、個々の HTTP 要求と応答に関するすべての情報がカプセル化されます。 HttpContext インスタンスは、HTTP 要求の受信時に初期化されます。 HttpContext インスタンスには、ミドルウェアや Web API コントローラー、Razor Pages、SignalR、gRPC などのアプリ フレームワークからアクセスできます。

HTTP の要求と応答での HttpContext の使用について詳しくは、「ASP.NET Core で HttpContext を使用する」をご覧ください。

HttpContext Pages から Razor にアクセスする

Razor Pages 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();
    }
}

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

次に例を示します。

  • UserRepositoryIHttpContextAccessor に対する依存関係を宣言します。
  • 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 になることがあります。

Note

アプリで NullReferenceException エラーが散発的に生成される場合、コードの中で、バックグラウンド処理を開始する部分や要求完了後に処理を続行する部分を見直してください。 コントローラー メソッドを async void として定義するなどの間違いを探します。

HttpContext データでバックグラウンド作業を安全に行うには:

  • 要求処理中に必要なデータをコピーします。
  • コピーしたデータをバックグラウンド タスクに渡します。
  • 並列タスクで データを参照 "しないで" ください。HttpContext 必要なデータは、並列タスクを開始する前にコンテキストから抽出してください。

アンセーフ コードを避けるために、バックグラウンド処理を行わないメソッドには HttpContext を決して渡さないでください。 代わりに必要なデータを渡してください。 次の例では、電子メールの送信を開始するために SendEmailSendEmailCoreAsync を呼びします。 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)

IHttpContextAccessor は、有効な HttpContext が常に使用できるわけではありませんので、対話型レンダリングでは一般に避ける必要があります。

IHttpContextAccessor は、サーバー上で静的にレンダリングされるコンポーネントに対して使用することができます。 ただし、可能であれば使用を避けることをお勧めします。

HttpContext は、 コンポーネント () 内のヘッダーやその他のプロパティの検査や変更などの一般的なタスク用に、"静的にレンダリングされたルート コンポーネント" 内でのみ、Appとして使用できます。Components/App.razor 対話型レンダリングの場合、この値は常に null です。

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

対話型コンポーネント内で HttpContext が必要なシナリオの場合は、サーバーから永続的なコンポーネントの状態を介してデータを取り込むことをお勧めします。 詳細については、コア サーバー側 ASP.NET および追加のセキュリティ シナリオ Blazor Web App 参照してください

サーバー側 IHttpContextAccessor アプリの / コンポーネントでは、HttpContextRazorBlazor を、直接にも間接的にも使用しないでください。 Blazor アプリは、ASP.NET Core パイプラインのコンテキストの外部で実行されます。 HttpContext は、IHttpContextAccessor 内で使用できるとは限りません。また、HttpContext は、Blazor アプリを開始したコンテキストが保持されることも保証されません。

アプリの初期レンダリング中にルート コンポーネント パラメーターを使って要求の状態を Blazor アプリに渡すことをお勧めします。 または、ルート コンポーネントの初期化ライフサイクル イベントにおいてアプリでスコープ サービスにデータをコピーすることで、アプリ全体で使用することもできます。 詳細については、コア サーバー側 ASP.NET および追加のセキュリティ シナリオ Blazor Web App 参照してください

サーバー側 Blazor のセキュリティでの重要な側面は、特定の回線に接続されているユーザーは Blazor 回線が確立された後のある時点で更新される可能性がありますが、IHttpContextAccessor は "更新されない" ということです。 カスタム サービスを使用してこのような状況に対処する方法の詳細については、「コア サーバー側ASP.NET および追加のセキュリティ シナリオBlazor Web Appを参照してください。

HttpContext を指定すると、個々の HTTP 要求と応答に関するすべての情報がカプセル化されます。 HttpContext インスタンスは、HTTP 要求の受信時に初期化されます。 HttpContext インスタンスには、ミドルウェアや Web API コントローラー、Razor Pages、SignalR、gRPC などのアプリ フレームワークからアクセスできます。

HTTP の要求と応答での HttpContext の使用について詳しくは、「ASP.NET Core で HttpContext を使用する」をご覧ください。

HttpContext Pages から Razor にアクセスする

Razor Pages 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 にアクセスする

カスタム ミドルウェア コンポーネントを使用する場合、HttpContextInvoke メソッドまたは 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>();
}

次に例を示します。

  • UserRepositoryIHttpContextAccessor に対する依存関係を宣言します。
  • 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 になることがあります。

Note

アプリで 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)

IHttpContextAccessor は、有効な HttpContext が常に使用できるわけではありませんので、対話型レンダリングでは一般に避ける必要があります。

IHttpContextAccessor は、サーバー上で静的にレンダリングされるコンポーネントに対して使用することができます。 ただし、可能であれば使用を避けることをお勧めします。

HttpContext は、 コンポーネント () 内のヘッダーやその他のプロパティの検査や変更などの一般的なタスク用に、"静的にレンダリングされたルート コンポーネント" 内でのみ、Appとして使用できます。Components/App.razor 対話型レンダリングの場合、この値は常に null です。

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

対話型コンポーネント内で HttpContext が必要なシナリオの場合は、サーバーから永続的なコンポーネントの状態を介してデータを取り込むことをお勧めします。 詳細については、コア サーバー側 ASP.NET および追加のセキュリティ シナリオ Blazor Web App 参照してください

サーバー側 IHttpContextAccessor アプリの / コンポーネントでは、HttpContextRazorBlazor を、直接にも間接的にも使用しないでください。 Blazor アプリは、ASP.NET Core パイプラインのコンテキストの外部で実行されます。 HttpContext は、IHttpContextAccessor 内で使用できるとは限りません。また、HttpContext は、Blazor アプリを開始したコンテキストが保持されることも保証されません。

アプリの初期レンダリング中にルート コンポーネント パラメーターを使って要求の状態を Blazor アプリに渡すことをお勧めします。 または、ルート コンポーネントの初期化ライフサイクル イベントにおいてアプリでスコープ サービスにデータをコピーすることで、アプリ全体で使用することもできます。 詳細については、コア サーバー側 ASP.NET および追加のセキュリティ シナリオ Blazor Web App 参照してください

サーバー側 Blazor のセキュリティでの重要な側面は、特定の回線に接続されているユーザーは Blazor 回線が確立された後のある時点で更新される可能性がありますが、IHttpContextAccessor は "更新されない" ということです。 カスタム サービスを使用してこのような状況に対処する方法の詳細については、「コア サーバー側ASP.NET および追加のセキュリティ シナリオBlazor Web Appを参照してください。