ASP.NET Core のエラーを処理する
发布时间:2026-09-04 | 浏览:1
📥 下载地址(文章开头)
このページにアクセスするには、承認が必要です。 サインイン または ディレクトリの変更 を試すことができます。
このページにアクセスするには、承認が必要です。 ディレクトリの変更 を試すことができます。
これは、この記事の最新バージョンではありません。 現在のリリースについては、 この記事の .NET 10 バージョンを 参照してください。
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシー を参照してください。 現在のリリースについては、 この記事の .NET 10 バージョンを 参照してください。
この記事では、ASP.NET Core Web アプリでエラーを処理するための一般的な手法について取り上げます。 「 ASP.NET Core API でのエラーの処理 」も参照してください。
この記事のガイダンスに追加されるまたは優先する Blazor エラー処理のガイダンスについては、「 ASP.NET Core Blazor アプリのエラーを処理する 」をご覧ください。
" 開発者例外ページ " には、未処理の要求の例外に関する詳細な情報が表示されます。 DeveloperExceptionPageMiddleware を使用して、HTTP パイプラインから同期および非同期例外をキャプチャし、エラー応答を生成します。 開発者例外ページは、後続のミドルウェアでスローされた未処理の例外をキャッチできるように、ミドルウェア パイプラインの早い段階で実行されます。
次の両方が当てはまる場合、ASP.NET Core アプリでは既定で開発者例外ページが有効になります。
Development 環境 で実行されています。
アプリが現在のテンプレート、つまり WebApplication.CreateBuilder を使用して作成された。
以前のテンプレート、つまり WebHost.CreateDefaultBuilder を使用して作成されたアプリは、 app.UseDeveloperExceptionPage を呼び出すことによって開発者例外ページを有効にすることができます。
Development 環境でアプリが実行されている場合を除き 、開発者例外ページを有効にしないでください。 アプリを運用環境で実行するときは、詳細な例外情報を公開しないでください。 環境の構成の詳細については、「 ASP.NET Core ランタイム環境 」を参照してください。
開発者例外ページには、例外と要求に関する次の情報が含まれている場合があります。
クエリ文字列のパラメーター (ある場合)
エンドポイント メタデータ (存在する場合)
開発者例外ページで何らかの情報が提供されるとは限りません。 完全なエラー情報については、 ログ記録 に関するページを参照してください。
次の図は、タブと表示される情報を示すアニメーション付きのサンプルの開発者例外ページを示しています。
Accept: text/plain ヘッダーを含む要求への応答で、開発者例外ページは HTML ではなくプレーン テキストを返します。 例えば次が挙げられます。
Production 環境 のカスタム エラー処理ページを構成するには、 UseExceptionHandler を呼び出します。 この例外処理ミドルウェアは、次のことを行います。
未処理の例外をキャッチしてログに記録します。
指定されたパスを使用して、別のパイプラインで要求を再実行します。 応答が始まっていた場合、要求は再実行されません。 テンプレートによって生成されたコードは、 /Error パスを使用して要求を再実行します。
代替パイプラインが別の例外をスローした場合、例外処理ミドルウェアは元の例外を再スローします。
このミドルウェアは要求パイプラインを再実行できるため:
ミドルウェアは、同じ要求での再入を処理する必要があります。 これは通常、 _next を呼び出した後で状態をクリーンアップすること、またはやり直しを避けるため処理を HttpContext にキャッシュすることを意味します。 要求本文を処理するときは、これはフォーム リーダーのような結果をバッファーまたはキャッシュすることを意味します。
テンプレートで使われる UseExceptionHandler(IApplicationBuilder, String) オーバーロードの場合、要求パスのみが変更され、ルート データはクリアされます。 ヘッダー、メソッド、項目などの要求データは、すべてそのまま再利用されます。
スコープ付きサービスは同じままです。
次の例では、 UseExceptionHandler は、 Development 以外の環境で例外処理ミドルウェアを追加します。
Razor Pages アプリのテンプレートには、エラー ページ ( .cshtml ) と PageModel クラス ( ErrorModel ) が Pages フォルダー内に用意されています。 MVC アプリの場合、プロジェクト テンプレートには、 Error コントローラー用の Home アクション メソッドとエラー ビューが含まれています。
例外処理ミドルウェアでは、" 元の " HTTP メソッドを使用して要求が再実行されます。 エラー ハンドラーのエンドポイントが特定の HTTP メソッドのセットに制限されている場合は、それらの HTTP メソッドに対してのみ実行されます。 たとえば、 [HttpGet] 属性を使用する MVC コントローラーのアクションは、GET 要求に対してのみ実行されます。 " すべての " 要求がカスタム エラー処理ページに到達するようにするために、それらを特定の HTTP メソッドのセットに制限しないでください。
元の HTTP メソッドに応じて例外を異なる方法で処理するには:
Razor Pages の場合は、複数のハンドラー メソッドを作成します。 たとえば、GET 例外を処理するために OnGet を使用し、POST 例外を処理するために OnPost を使用します。
MVC の場合は、複数のアクションに HTTP 動詞属性を適用します。 たとえば、GET 例外を処理するために [HttpGet] を使用し、POST 例外を処理するために [HttpPost] を使用します。
認証されていないユーザーがカスタム エラー処理ページを表示できるようにするには、匿名アクセスがサポートされるようにします。
エラー ハンドラーで例外や元の要求パスにアクセスするには、 IExceptionHandlerPathFeature を使います。 次の例では、 IExceptionHandlerPathFeature を使用して、スローされた例外に関する詳細を取得しています。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使うと、応答を返す前にエラーにアクセスできます。
次のコードは、例外処理にラムダを使用しています。
ラムダを使用するもう 1 つの方法は、次の例のように、例外の種類に基づいて状態コードを設定することです。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
IExceptionHandler
IExceptionHandler は、既知の例外を処理するコールバックを、一元化された場所で開発者に提供するインターフェイスです。 インターフェイスには、 TryHandleAsync と HttpContext パラメーターを受け取る 1 つのメソッド ( Exception ) が含まれています。
IExceptionHandler の実装は、 IServiceCollection.AddExceptionHandler<T> を呼び出すことで登録されます。 IExceptionHandler インスタンスの有効期間はシングルトンです。 複数の実装を追加することが可能で、登録された順序で呼び出されます。
IExceptionHandler 実装を登録するだけでは不十分です。 登録されたハンドラーは例外処理ミドルウェアによって呼び出されるため、アプリは UseExceptionHandler を呼び出してそのミドルウェアを追加する必要もあります。 UseExceptionHandler が呼び出されない場合、登録済みの IExceptionHandler 実装は呼び出されません。
例外処理ミドルウェアは、登録された例外ハンドラーを順番に反復処理し、例外が処理されたことを示す true から TryHandleAsync を返します。 例外ハンドラーが例外を処理する場合は、 true を返して処理を停止できます。 例外ハンドラーによって例外が処理されない場合、ミドルウェアの既定の動作とオプションに制御がフォールバックされます。
.NET 10 以降では、既定の動作は、処理された例外のログやメトリックなどの診断の出力を抑制することです ( TryHandleAsync が true を返す場合)。 これは、例外が処理されたかどうかに関係なく、常に診断が生成された以前のバージョン (.NET 8 および 9) とは異なります。 既定の動作は、 SuppressDiagnosticsCallback を設定することで変更できます。
次の例は IExceptionHandler の実装を示しています。
次の例は、依存関係の挿入用に IExceptionHandler 実装を登録し、それを呼び出す例外処理ミドルウェアを追加する方法を示しています。
IExceptionHandler を使用する際に UseExceptionHandler を構成する
例外処理ミドルウェアには、 IExceptionHandler で処理されない例外に対するフォールバック処理が必要です。 何も構成されていない場合、引数を指定しない app.UseExceptionHandler() を呼び出すと、起動時に次の例外がスローされます。
System.InvalidOperationException: An error occurred when configuring the exception handler middleware. Either the 'ExceptionHandlingPath' or the 'ExceptionHandler' property must be set in 'UseExceptionHandler()'.
要件を満たすには、次のいずれかを使用します。
エラー パスを指定します。 app.UseExceptionHandler("/Error");
問題の詳細を有効にする: builder.Services.AddProblemDetails(); を呼び出してから app.UseExceptionHandler();
フォールバック ハンドラーを指定します。 app.UseExceptionHandler(exceptionHandlerApp => { ... });
IExceptionHandler の実装は、これらすべてのケースで引き続き最初に実行されます。 構成されたパス、問題の詳細の応答、またはフォールバック ハンドラーは、すべての TryHandleAsync が false を返す場合にのみ使用されます。
IExceptionHandler が応答を記述したり状態コードを設定したりせずに true を返した場合、応答は 404 Not Found になり、ミドルウェア ログが記録されます。
The exception handler configured on ExceptionHandlerOptions produced a 404 status response.
true を返す IExceptionHandler は、状態コードを含む完全な応答を記述する必要があります。 たとえば、 httpContext.Response.StatusCode 設定して本文を記述したり、 IProblemDetailsService.TryWriteAsync を呼び出したりします。 404 応答が意図的な場合は、 AllowStatusCode404Response を true に設定します。
上記のコードが Development 環境で実行される場合:
例外を処理するために CustomExceptionHandler がまず呼び出されます。
例外をログに記録した後、 TryHandleAsync メソッドは false を返します。そのため、 開発者例外ページ が表示されます。
例外を処理するために CustomExceptionHandler がまず呼び出されます。
例外をログに記録した後、 TryHandleAsync メソッドは false を返します。そのため、 /Error ページ が表示されます。
TryHandleAsync が代わりに true を返す場合:
残りの IExceptionHandler 実装は呼び出されません。
UseExceptionHandler で構成された例外ハンドラー のページ、パス、またはラムダは使用されません。 ハンドラーは、応答全体を書き込む役割を担います。
SuppressDiagnosticsCallback
.NET 10 以降では、例外処理ミドルウェアが処理された例外の診断を書き込むかどうかを制御するには、 SuppressDiagnosticsCallback で ExceptionHandlerOptions プロパティを構成します。 このコールバックは例外コンテキストを受け取り、特定の例外または要求に基づいて診断を抑制するかどうかを判断できます。
処理された例外に対して常に診断が出力される .NET 8 および 9 の動作に戻すには、コールバックを常に false 返すように設定します。
例外の種類やその他のコンテキストに基づいて、条件付きで診断を抑制することもできます。
例外が IExceptionHandler 実装によって処理されない場合 (すべてのハンドラーが false から TryHandleAsync を返す)、コントロールはミドルウェアの既定の動作とオプションにフォールバックし、ミドルウェアの標準動作に従って診断が生成されます。
UseStatusCodePages
ASP.NET Core アプリでは、既定で、" 404 - 見つかりません " などの HTTP エラー状態コードの状態コード ページが表示されません。 アプリで、本文のない HTTP 400 から 599 のエラー状態コードが設定されると、状態コードと空の応答本文が返されます。 一般的なエラー状態コード用に既定のテキスト専用ハンドラーを有効にするには、 UseStatusCodePages で Program.cs を呼び出します。
要求処理ミドルウェアの前に UseStatusCodePages を呼び出します。 たとえば、静的ファイル ミドルウェアとエンドポイント ミドルウェアの前に UseStatusCodePages を呼び出します。
UseStatusCodePages を使用しない場合、エンドポイントなしで URL に移動すると、エンドポイントが見つからないことを示すブラウザー依存のエラー メッセージが返されます。 UseStatusCodePages が呼び出されると、ブラウザーにより次の応答が返されます。
UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
状態コード ページのミドルウェアは例外をキャッチ しません 。 カスタム エラー処理ページを提供するには、 例外ハンドラー ページ を使用します。
書式設定文字列での UseStatusCodePages
応答の内容の種類とテキストをカスタマイズするには、内容の種類と書式文字列を受け取る UseStatusCodePages のオーバーロードを使います。
上記のコードでは、 {0} はエラー コードのプレースホルダーです。
書式指定文字列を含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
ラムダでの UseStatusCodePages
カスタム エラー処理と応答書き込みコードを指定するには、ラムダ式を受け取る UseStatusCodePages のオーバーロードを使います。
ラムダを含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects 拡張メソッド:
クライアントに 302 - Found 状態コードを送信します。
URL テンプレートで指定されているエラー処理エンドポイントにクライアントをリダイレクトします。 エラー処理エンドポイントには、通常、エラー情報が表示され、HTTP 200 が返されます。
前のコードに示されているように、URL テンプレートには状態コード用の {0} プレースホルダーを含めることができます。 URL テンプレートが ~ (チルダ) で始まっている場合、 ~ はアプリの PathBase に置き換えられます。 アプリでエンドポイントを指定するときに、そのエンドポイントの MVC ビューまたは Razor ページを作成します。
この方法は、次のようなアプリで一般的に使用されます。
クライアントを別のエンドポイントにリダイレクトする必要がある場合 (通常は、別のアプリがエラーを処理する場合)。 Web アプリの場合は、クライアントのブラウザーのアドレス バーにリダイレクトされたエンドポイントが反映されます。
元のステータス コードを保持して最初のリダイレクト応答で返すべきではない。
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute 拡張メソッド:
代替パスを使用して要求パイプラインを再実行することで、応答本文を生成します。
パイプラインの再実行前または再実行後に状態コードを変更しません。
新しいパイプラインでは状態コードが完全に制御されるため、新しいパイプラインの実行によって応答の状態コードが変更される可能性があります。 新しいパイプラインで状態コードが変更されない場合、元の状態コードがクライアントに送信されます。
アプリ内でエンドポイントが指定されている場合は、そのエンドポイントの MVC ビューまたは Razor ページを作成します。
この方法は、アプリで次のことを行う必要がある場合によく使用されます。
別のエンドポイントにリダイレクトすることなく要求を処理する。 Web アプリの場合は、クライアントのブラウザーのアドレス バーに、初めに要求されていたエンドポイントが反映されます。
元の状態コードを保持し、応答で返す。
URL テンプレートは / で始まる必要があります。このテンプレートには、状態コード用のプレースホルダー {0} を含めることができます。 状態コードをクエリ文字列パラメーターとして渡すには、2 番目の引数を UseStatusCodePagesWithReExecute に渡します。 例えば次が挙げられます。
次の例で示すように、エラーを処理するエンドポイントでは、エラーを生成した元の URL を取得できます。
このミドルウェアは要求パイプラインを再実行できるため:
ミドルウェアは、同じ要求での再入を処理する必要があります。 これは通常、 _next を呼び出した後で状態をクリーンアップすること、またはやり直しを避けるため処理を HttpContext にキャッシュすることを意味します。 要求本文を処理するときは、これはフォーム リーダーのような結果をバッファーまたはキャッシュすることを意味します。
スコープ付きサービスは同じままです。
状態コード ページを無効にする
MVC コントローラーまたはアクション メソッドの状態コード ページを無効にするには、 [SkipStatusCodePages] 属性を使用します。
Razor Pages ハンドラー メソッドまたは MVC コントローラーの特定の要求に対して状態コード ページを無効にするには、 IStatusCodePagesFeature を使用します。
例外処理ページのコードが例外をスローすることもあります。 運用環境のエラー ページは十分にテストし、それ自体から例外がスローされないように特に注意する必要があります。
応答のヘッダーが送信された後は、次のようになります。
アプリで応答の状態コードを変更できません。
すべての例外ページやハンドラーを実行できません。 応答は完了している必要があります。あるいは、接続が中止となっている必要があります。
アプリ内の例外処理ロジックに加えて、 HTTP サーバーの実装 でも一部の例外を処理できます。 応答ヘッダーの送信前にサーバーで例外がキャッチされると、サーバーによって " 500 - Internal Server Error " 応答が応答本文なしで送信されます。 応答ヘッダーの送信後にサーバーで例外がキャッチされた場合、サーバーは接続を閉じます。 アプリで処理されない要求はサーバーで処理されます。 サーバーが要求を処理しているときに発生した例外は、すべてサーバーの例外処理によって処理されます。 この動作は、アプリのカスタム エラー ページ、例外処理ミドルウェア、およびフィルターから影響を受けません。
アプリの起動中に起こる例外はホスティング層だけが処理できます。 起動時のエラーをキャプチャ したり、 詳細なエラーをキャプチャ したりするように、ホストを構成することができます。
ホスティング レイヤーでは、ホスト アドレス/ポート バインド後にエラーが発生した場合にのみ、キャプチャされた起動時エラーに対するエラー ページを表示できます。 バインドが失敗した場合は、次のようになります。
ホスティング レイヤーにより重大な例外がログに記録されます。
dotnet プロセスがクラッシュします。
HTTP サーバーが Kestrel のときは、エラー ページは表示されません。
IIS (または Azure App Service) または IIS Express 上で実行している場合、プロセスを開始できなければ、 ASP.NET Core モジュール から " 502.5 - 処理エラー " が返されます。 詳細については、「 Azure App Service および IIS での ASP.NET Core のトラブルシューティング 」を参照してください。
データベース開発者ページ例外フィルター AddDatabaseDeveloperPageExceptionFilter では、Entity Framework Core の移行を使って解決できるデータベース関連の例外がキャプチャされます。 これらの例外が発生すると、問題が解決する可能性のあるアクションの詳細を含む HTML 応答が生成されます。 このページは、 Development 環境でのみ有効になります。 次のコードでは、データベース開発者ページの例外フィルターを追加しています。
MVC アプリでは、例外フィルターをグローバルに、またはコントローラーやアクションの単位で構成できます。 Razor Pages アプリでは、グローバルに、またはページ モデルの単位で構成できます。 このようなフィルターは、コントローラー アクションや別のフィルターの実行中に発生する未処理の例外を処理します。 詳細については、「 ASP.NET Core フィルター 」を参照してください。
例外フィルターは、MVC アクション内で発生する例外をトラップする場合には便利ですが、組み込みの 例外処理ミドルウェア UseExceptionHandler ほど柔軟ではありません。 選択された MVC アクションに応じて異なる方法でエラー処理を実行する必要がある場合を除き、 UseExceptionHandler を使用することをお勧めします。
モデル状態エラーを処理する方法については、 モデル バインド および モデルの検証 に関する記事をご覧ください。
問題の詳細 は、HTTP API エラーを記述する唯一の応答形式ではありませんが、一般的に HTTP API のエラーを報告するために使用されます。
問題の詳細サービスは、 IProblemDetailsService インターフェイスを実装し、これにより、ASP.NET Core での問題の詳細の作成がサポートされます。 AddProblemDetails(IServiceCollection) の IServiceCollection 拡張メソッドは、既定の IProblemDetailsService 実装を登録します。
ASP.NET Core アプリでは、次のミドルウェアによって、 AddProblemDetails が呼び出されたときに問題の詳細 HTTP 応答が生成されます。ただし、 Accept 要求 HTTP ヘッダー に、登録された IProblemDetailsWriter (既定値: application/json ) によってサポートされるいずれかのコンテンツ タイプが含まれていない場合を除きます。
ExceptionHandlerMiddleware : カスタム ハンドラーが定義されていない場合に、問題の詳細の応答を生成します。
StatusCodePagesMiddleware : 既定で問題の詳細の応答を生成します。
DeveloperExceptionPageMiddleware : 開発中に Accept 要求 HTTP ヘッダーに text/html が含まれていない場合に、問題の詳細応答を生成します。
次のコードは、すべての HTTP クライアント用の " 本文コンテンツがまだ含まれていない " 問題の詳細応答とサーバー エラー応答を生成するようにアプリを構成します。
次のセクションでは、問題の詳細の応答の本文をカスタマイズする方法を示します。
ProblemDetails の自動作成は、次のどのオプションでもカスタマイズできます。
ProblemDetailsOptions.CustomizeProblemDetails を使用します
カスタム IProblemDetailsWriter を使用する
ミドルウェアで IProblemDetailsService を呼び出す
CustomizeProblemDetails 操作
生成された問題の詳細は CustomizeProblemDetails を使用してカスタマイズでき、カスタマイズはすべての自動生成された問題の詳細に適用されます。
次のコードは ProblemDetailsOptions を使用して CustomizeProblemDetails を設定します。
たとえば、 HTTP Status 400 Bad Request エンドポイントの結果により、次の問題の詳細の応答本文が生成されます。
カスタム IProblemDetailsWriter
高度なカスタマイズのために IProblemDetailsWriter の実装を作成できます。
注: カスタムの IProblemDetailsWriter を使う場合は、 IProblemDetailsWriter 、 AddRazorPages 、 AddControllers 、または AddControllersWithViews を呼び出す前にカスタムの AddMvc を登録する必要があります。
ProblemDetailsOptions を CustomizeProblemDetails と共に使用する別の方法として、ミドルウェアで ProblemDetails を設定します。 問題の詳細の応答は、 IProblemDetailsService.WriteAsync を呼び出すことによって書き込むことができます。
前のコードでは、最小 API エンドポイント /divide と /squareroot は、エラー入力時に予期されるカスタム問題の応答を返します。
API コントローラー エンドポイントは、カスタムの問題の応答ではなく、エラー入力で既定の問題の応答を返します。 既定の問題応答が返されるのは、 が呼び出される前に API コントローラーが応答ストリームに IProblemDetailsService.WriteAsync を書き込み、その後、応答が再度 書き込まれない ためです。
次の ValuesController は BadRequestResult を返します。これは、応答ストリームに書き込むため、カスタムの問題の応答が返されるのを回避します。
次の Values3Controller は ControllerBase.Problem を返すため、予期されるカスタム問題の結果が返されます。
例外に対する ProblemDetails ペイロードを生成する
次のアプリを考えてみましょう。
非開発環境では、例外が発生した場合、以下が、クライアントに返される標準の ProblemDetails 応答 です。
ほとんどのアプリでは、例外に必要なコードは上記ですべてです。 ただし、次のセクションでは、より詳細な問題の応答を取得する方法を示します。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使用すると、エラーにアクセスし、 IProblemDetailsService.WriteAsync を使用して問題の詳細の応答を書き込むことができます。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
問題の詳細を生成する別の方法としては、例外とクライアント エラーを問題の詳細にマップするために使用できるサードパーティの NuGet パッケージ Hellang.Middleware.ProblemDetails を使います。
サンプル コードを表示またはダウンロード します ( ダウンロード方法 )。
Azure App Service および IIS での ASP.NET Core のトラブルシューティング
ASP.NET Core を使用した Azure App Service および IIS の一般的なエラーのトラブルシューティング
ASP.NET Core API のエラーを処理する
破壊的変更: IExceptionHandler.TryHandleAsync が true を返すと例外診断が抑制される
この記事では、ASP.NET Core Web アプリでエラーを処理するための一般的な手法について取り上げます。 「 ASP.NET Core API でのエラーの処理 」も参照してください。
この記事のガイダンスに追加されるまたは優先する Blazor エラー処理のガイダンスについては、「 ASP.NET Core Blazor アプリのエラーを処理する 」をご覧ください。
" 開発者例外ページ " には、未処理の要求の例外に関する詳細な情報が表示されます。 DeveloperExceptionPageMiddleware を使用して、HTTP パイプラインから同期および非同期例外をキャプチャし、エラー応答を生成します。 開発者例外ページは、後続のミドルウェアでスローされた未処理の例外をキャッチできるように、ミドルウェア パイプラインの早い段階で実行されます。
次の両方が当てはまる場合、ASP.NET Core アプリでは既定で開発者例外ページが有効になります。
Development 環境 で実行されています。
アプリが現在のテンプレート、つまり WebApplication.CreateBuilder を使用して作成された。
以前のテンプレート、つまり WebHost.CreateDefaultBuilder を使用して作成されたアプリは、 app.UseDeveloperExceptionPage を呼び出すことによって開発者例外ページを有効にすることができます。
Development 環境でアプリが実行されている場合を除き 、開発者例外ページを有効にしないでください。 アプリを運用環境で実行するときは、詳細な例外情報を公開しないでください。 環境の構成の詳細については、「 ASP.NET Core ランタイム環境 」を参照してください。
開発者例外ページには、例外と要求に関する次の情報が含まれている場合があります。
クエリ文字列のパラメーター (ある場合)
エンドポイント メタデータ (存在する場合)
開発者例外ページで何らかの情報が提供されるとは限りません。 完全なエラー情報については、 ログ記録 に関するページを参照してください。
次の図は、タブと表示される情報を示すアニメーション付きのサンプルの開発者例外ページを示しています。
Accept: text/plain ヘッダーを含む要求への応答で、開発者例外ページは HTML ではなくプレーン テキストを返します。 例えば次が挙げられます。
Production 環境 のカスタム エラー処理ページを構成するには、 UseExceptionHandler を呼び出します。 この例外処理ミドルウェアは、次のことを行います。
未処理の例外をキャッチしてログに記録します。
指定されたパスを使用して、別のパイプラインで要求を再実行します。 応答が始まっていた場合、要求は再実行されません。 テンプレートによって生成されたコードは、 /Error パスを使用して要求を再実行します。
代替パイプラインが別の例外をスローした場合、例外処理ミドルウェアは元の例外を再スローします。
このミドルウェアは要求パイプラインを再実行できるため:
ミドルウェアは、同じ要求での再入を処理する必要があります。 これは通常、 _next を呼び出した後で状態をクリーンアップすること、またはやり直しを避けるため処理を HttpContext にキャッシュすることを意味します。 要求本文を処理するときは、これはフォーム リーダーのような結果をバッファーまたはキャッシュすることを意味します。
テンプレートで使われる UseExceptionHandler(IApplicationBuilder, String) オーバーロードの場合、要求パスのみが変更され、ルート データはクリアされます。 ヘッダー、メソッド、項目などの要求データは、すべてそのまま再利用されます。
スコープ付きサービスは同じままです。
次の例では、 UseExceptionHandler は、 Development 以外の環境で例外処理ミドルウェアを追加します。
Razor Pages アプリのテンプレートには、エラー ページ ( .cshtml ) と PageModel クラス ( ErrorModel ) が Pages フォルダー内に用意されています。 MVC アプリの場合、プロジェクト テンプレートには、 Error コントローラー用の Home アクション メソッドとエラー ビューが含まれています。
例外処理ミドルウェアでは、" 元の " HTTP メソッドを使用して要求が再実行されます。 エラー ハンドラーのエンドポイントが特定の HTTP メソッドのセットに制限されている場合は、それらの HTTP メソッドに対してのみ実行されます。 たとえば、 [HttpGet] 属性を使用する MVC コントローラーのアクションは、GET 要求に対してのみ実行されます。 " すべての " 要求がカスタム エラー処理ページに到達するようにするために、それらを特定の HTTP メソッドのセットに制限しないでください。
元の HTTP メソッドに応じて例外を異なる方法で処理するには:
Razor Pages の場合は、複数のハンドラー メソッドを作成します。 たとえば、GET 例外を処理するために OnGet を使用し、POST 例外を処理するために OnPost を使用します。
MVC の場合は、複数のアクションに HTTP 動詞属性を適用します。 たとえば、GET 例外を処理するために [HttpGet] を使用し、POST 例外を処理するために [HttpPost] を使用します。
認証されていないユーザーがカスタム エラー処理ページを表示できるようにするには、匿名アクセスがサポートされるようにします。
エラー ハンドラーで例外や元の要求パスにアクセスするには、 IExceptionHandlerPathFeature を使います。 次の例では、 IExceptionHandlerPathFeature を使用して、スローされた例外に関する詳細を取得しています。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使うと、応答を返す前にエラーにアクセスできます。
次のコードは、例外処理にラムダを使用しています。
ラムダを使用するもう 1 つの方法は、次の例のように、例外の種類に基づいて状態コードを設定することです。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
IExceptionHandler
IExceptionHandler は、既知の例外を処理するコールバックを、一元化された場所で開発者に提供するインターフェイスです。
IExceptionHandler の実装は、 IServiceCollection.AddExceptionHandler<T> を呼び出すことで登録されます。 IExceptionHandler インスタンスの有効期間はシングルトンです。 複数の実装を追加することが可能で、登録された順序で呼び出されます。
IExceptionHandler 実装を登録するだけでは不十分です。 登録されたハンドラーは例外処理ミドルウェアによって呼び出されるため、アプリは UseExceptionHandler を呼び出してそのミドルウェアを追加する必要もあります。 UseExceptionHandler が呼び出されない場合、登録済みの IExceptionHandler 実装は呼び出されません。
例外処理ミドルウェアは、登録された例外ハンドラーを順番に反復処理し、例外が処理されたことを示す true から TryHandleAsync を返します。 例外ハンドラーが例外を処理する場合は、 true を返して処理を停止できます。 例外ハンドラーによって例外が処理されない場合、ミドルウェアの既定の動作とオプションに制御がフォールバックされます。
.NET 8 と .NET 9 では、例外処理ミドルウェアは例外をログに記録し、 IExceptionHandler 実装が TryHandleAsync から true を返した場合でもメトリックを出力します。 ハンドラーが独自のログ記録を行う場合、例外は 2 回記録されます。1 回は Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware カテゴリの下に 1 回、ハンドラーのカテゴリの下に 1 回記録されます。 ハンドラーからのみログに記録するには、構成でミドルウェア カテゴリを除外します。
.NET 10 以降では、処理された例外の診断は既定で抑制されます。 SuppressDiagnosticsCallback を 参照してください。
次の例は IExceptionHandler の実装を示しています。
次の例は、依存関係の挿入用に IExceptionHandler 実装を登録し、それを呼び出す例外処理ミドルウェアを追加する方法を示しています。
IExceptionHandler を使用する際に UseExceptionHandler を構成する
例外処理ミドルウェアには、 IExceptionHandler で処理されない例外に対するフォールバック処理が必要です。 何も構成されていない場合、引数なしで app.UseExceptionHandler() を呼び出すと、起動時にスローされます。
System.InvalidOperationException: An error occurred when configuring the exception handler middleware. Either the 'ExceptionHandlingPath' or the 'ExceptionHandler' property must be set in 'UseExceptionHandler()'.
要件を満たすには、次のいずれかを使用します。
エラー パスを指定します。 app.UseExceptionHandler("/Error");
問題の詳細を有効にする: builder.Services.AddProblemDetails(); を呼び出してから app.UseExceptionHandler();
フォールバック ハンドラーを指定します。 app.UseExceptionHandler(exceptionHandlerApp => { ... });
IExceptionHandler の実装は、これらすべてのケースで引き続き最初に実行されます。 構成されたパス、問題の詳細の応答、またはフォールバック ハンドラーは、すべての TryHandleAsync が false を返す場合にのみ使用されます。
IExceptionHandler が応答を記述したり状態コードを設定したりせずに true を返した場合、応答は 404 Not Found になり、ミドルウェア ログが記録されます。
The exception handler configured on ExceptionHandlerOptions produced a 404 status response.
true を返す IExceptionHandler は、状態コードを含む完全な応答を記述する必要があります。 たとえば、 httpContext.Response.StatusCode 設定して本文を記述したり、 IProblemDetailsService.TryWriteAsync を呼び出したりします。 404 応答が意図的な場合は、 AllowStatusCode404Response を true に設定します。
上記のコードが Development 環境で実行される場合:
例外を処理するために CustomExceptionHandler がまず呼び出されます。
例外をログに記録した後、 TryHandleAsync メソッドは false を返します。そのため、 開発者例外ページ が表示されます。
例外を処理するために CustomExceptionHandler がまず呼び出されます。
例外をログに記録した後、 TryHandleAsync メソッドは false を返します。そのため、 /Error ページ が表示されます。
TryHandleAsync が代わりに true を返す場合:
残りの IExceptionHandler 実装は呼び出されません。
UseExceptionHandler で構成された例外ハンドラー のページ、パス、またはラムダは使用されません。 ハンドラーは、応答全体を書き込む役割を担います。
UseStatusCodePages
ASP.NET Core アプリでは、既定で、" 404 - 見つかりません " などの HTTP エラー状態コードの状態コード ページが表示されません。 アプリで、本文のない HTTP 400 から 599 のエラー状態コードが設定されると、状態コードと空の応答本文が返されます。 一般的なエラー状態コード用に既定のテキスト専用ハンドラーを有効にするには、 UseStatusCodePages で Program.cs を呼び出します。
要求処理ミドルウェアの前に UseStatusCodePages を呼び出します。 たとえば、静的ファイル ミドルウェアとエンドポイント ミドルウェアの前に UseStatusCodePages を呼び出します。
UseStatusCodePages を使用しない場合、エンドポイントなしで URL に移動すると、エンドポイントが見つからないことを示すブラウザー依存のエラー メッセージが返されます。 UseStatusCodePages が呼び出されると、ブラウザーにより次の応答が返されます。
UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
状態コード ページのミドルウェアは例外をキャッチ しません 。 カスタム エラー処理ページを提供するには、 例外ハンドラー ページ を使用します。
書式設定文字列での UseStatusCodePages
応答の内容の種類とテキストをカスタマイズするには、内容の種類と書式文字列を受け取る UseStatusCodePages のオーバーロードを使います。
上記のコードでは、 {0} はエラー コードのプレースホルダーです。
書式指定文字列を含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
ラムダでの UseStatusCodePages
カスタム エラー処理と応答書き込みコードを指定するには、ラムダ式を受け取る UseStatusCodePages のオーバーロードを使います。
ラムダを含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects 拡張メソッド:
クライアントに 302 - Found 状態コードを送信します。
URL テンプレートで指定されているエラー処理エンドポイントにクライアントをリダイレクトします。 エラー処理エンドポイントには、通常、エラー情報が表示され、HTTP 200 が返されます。
前のコードに示されているように、URL テンプレートには状態コード用の {0} プレースホルダーを含めることができます。 URL テンプレートが ~ (チルダ) で始まっている場合、 ~ はアプリの PathBase に置き換えられます。 アプリでエンドポイントを指定するときに、そのエンドポイントの MVC ビューまたは Razor ページを作成します。
この方法は、次のようなアプリで一般的に使用されます。
クライアントを別のエンドポイントにリダイレクトする必要がある場合 (通常は、別のアプリがエラーを処理する場合)。 Web アプリの場合は、クライアントのブラウザーのアドレス バーにリダイレクトされたエンドポイントが反映されます。
元のステータス コードを保持して最初のリダイレクト応答で返すべきではない。
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute 拡張メソッド:
代替パスを使用して要求パイプラインを再実行することで、応答本文を生成します。
パイプラインの再実行前または再実行後に状態コードを変更しません。
新しいパイプラインでは状態コードが完全に制御されるため、新しいパイプラインの実行によって応答の状態コードが変更される可能性があります。 新しいパイプラインで状態コードが変更されない場合、元の状態コードがクライアントに送信されます。
アプリ内でエンドポイントが指定されている場合は、そのエンドポイントの MVC ビューまたは Razor ページを作成します。
この方法は、アプリで次のことを行う必要がある場合によく使用されます。
別のエンドポイントにリダイレクトすることなく要求を処理する。 Web アプリの場合は、クライアントのブラウザーのアドレス バーに、初めに要求されていたエンドポイントが反映されます。
元の状態コードを保持し、応答で返す。
URL テンプレートは / で始まる必要があります。このテンプレートには、状態コード用のプレースホルダー {0} を含めることができます。 状態コードをクエリ文字列パラメーターとして渡すには、2 番目の引数を UseStatusCodePagesWithReExecute に渡します。 例えば次が挙げられます。
次の例で示すように、エラーを処理するエンドポイントでは、エラーを生成した元の URL を取得できます。
このミドルウェアは要求パイプラインを再実行できるため:
ミドルウェアは、同じ要求での再入を処理する必要があります。 これは通常、 _next を呼び出した後で状態をクリーンアップすること、またはやり直しを避けるため処理を HttpContext にキャッシュすることを意味します。 要求本文を処理するときは、これはフォーム リーダーのような結果をバッファーまたはキャッシュすることを意味します。
スコープ付きサービスは同じままです。
状態コード ページを無効にする
MVC コントローラーまたはアクション メソッドの状態コード ページを無効にするには、 [SkipStatusCodePages] 属性を使用します。
Razor Pages ハンドラー メソッドまたは MVC コントローラーの特定の要求に対して状態コード ページを無効にするには、 IStatusCodePagesFeature を使用します。
例外処理ページのコードが例外をスローすることもあります。 運用環境のエラー ページは十分にテストし、それ自体から例外がスローされないように特に注意する必要があります。
応答のヘッダーが送信された後は、次のようになります。
アプリで応答の状態コードを変更できません。
すべての例外ページやハンドラーを実行できません。 応答は完了している必要があります。あるいは、接続が中止となっている必要があります。
アプリ内の例外処理ロジックに加えて、 HTTP サーバーの実装 でも一部の例外を処理できます。 応答ヘッダーの送信前にサーバーで例外がキャッチされると、サーバーによって " 500 - Internal Server Error " 応答が応答本文なしで送信されます。 応答ヘッダーの送信後にサーバーで例外がキャッチされた場合、サーバーは接続を閉じます。 アプリで処理されない要求はサーバーで処理されます。 サーバーが要求を処理しているときに発生した例外は、すべてサーバーの例外処理によって処理されます。 この動作は、アプリのカスタム エラー ページ、例外処理ミドルウェア、およびフィルターから影響を受けません。
アプリの起動中に起こる例外はホスティング層だけが処理できます。 起動時のエラーをキャプチャ したり、 詳細なエラーをキャプチャ したりするように、ホストを構成することができます。
ホスティング レイヤーでは、ホスト アドレス/ポート バインド後にエラーが発生した場合にのみ、キャプチャされた起動時エラーに対するエラー ページを表示できます。 バインドが失敗した場合は、次のようになります。
ホスティング レイヤーにより重大な例外がログに記録されます。
dotnet プロセスがクラッシュします。
HTTP サーバーが Kestrel のときは、エラー ページは表示されません。
IIS (または Azure App Service) または IIS Express 上で実行している場合、プロセスを開始できなければ、 ASP.NET Core モジュール から " 502.5 - 処理エラー " が返されます。 詳細については、「 Azure App Service および IIS での ASP.NET Core のトラブルシューティング 」を参照してください。
データベース開発者ページ例外フィルター AddDatabaseDeveloperPageExceptionFilter では、Entity Framework Core の移行を使って解決できるデータベース関連の例外がキャプチャされます。 これらの例外が発生すると、問題が解決する可能性のあるアクションの詳細を含む HTML 応答が生成されます。 このページは、 Development 環境でのみ有効になります。 次のコードでは、データベース開発者ページの例外フィルターを追加しています。
MVC アプリでは、例外フィルターをグローバルに、またはコントローラーやアクションの単位で構成できます。 Razor Pages アプリでは、グローバルに、またはページ モデルの単位で構成できます。 このようなフィルターは、コントローラー アクションや別のフィルターの実行中に発生する未処理の例外を処理します。 詳細については、「 ASP.NET Core フィルター 」を参照してください。
例外フィルターは、MVC アクション内で発生する例外をトラップする場合には便利ですが、組み込みの 例外処理ミドルウェア UseExceptionHandler ほど柔軟ではありません。 選択された MVC アクションに応じて異なる方法でエラー処理を実行する必要がある場合を除き、 UseExceptionHandler を使用することをお勧めします。
モデル状態エラーを処理する方法については、 モデル バインド および モデルの検証 に関する記事をご覧ください。
問題の詳細 は、HTTP API エラーを記述する唯一の応答形式ではありませんが、一般的に HTTP API のエラーを報告するために使用されます。
問題の詳細サービスは、 IProblemDetailsService インターフェイスを実装し、これにより、ASP.NET Core での問題の詳細の作成がサポートされます。 AddProblemDetails(IServiceCollection) の IServiceCollection 拡張メソッドは、既定の IProblemDetailsService 実装を登録します。
ASP.NET Core アプリでは、次のミドルウェアによって、 AddProblemDetails が呼び出されたときに問題の詳細 HTTP 応答が生成されます。ただし、 Accept 要求 HTTP ヘッダー に、登録された IProblemDetailsWriter (既定値: application/json ) によってサポートされるいずれかのコンテンツ タイプが含まれていない場合を除きます。
ExceptionHandlerMiddleware : カスタム ハンドラーが定義されていない場合に、問題の詳細の応答を生成します。
StatusCodePagesMiddleware : 既定で問題の詳細の応答を生成します。
DeveloperExceptionPageMiddleware : 開発中に Accept 要求 HTTP ヘッダーに text/html が含まれていない場合に、問題の詳細応答を生成します。
次のコードは、すべての HTTP クライアント用の " 本文コンテンツがまだ含まれていない " 問題の詳細応答とサーバー エラー応答を生成するようにアプリを構成します。
次のセクションでは、問題の詳細の応答の本文をカスタマイズする方法を示します。
ProblemDetails の自動作成は、次のどのオプションでもカスタマイズできます。
ProblemDetailsOptions.CustomizeProblemDetails を使用します
カスタム IProblemDetailsWriter を使用する
ミドルウェアで IProblemDetailsService を呼び出す
CustomizeProblemDetails 操作
生成された問題の詳細は CustomizeProblemDetails を使用してカスタマイズでき、カスタマイズはすべての自動生成された問題の詳細に適用されます。
次のコードは ProblemDetailsOptions を使用して CustomizeProblemDetails を設定します。
たとえば、 HTTP Status 400 Bad Request エンドポイントの結果により、次の問題の詳細の応答本文が生成されます。
カスタム IProblemDetailsWriter
高度なカスタマイズのために IProblemDetailsWriter の実装を作成できます。
注: カスタムの IProblemDetailsWriter を使う場合は、 IProblemDetailsWriter 、 AddRazorPages 、 AddControllers 、または AddControllersWithViews を呼び出す前にカスタムの AddMvc を登録する必要があります。
ProblemDetailsOptions を CustomizeProblemDetails と共に使用する別の方法として、ミドルウェアで ProblemDetails を設定します。 問題の詳細の応答は、 IProblemDetailsService.WriteAsync を呼び出すことによって書き込むことができます。
前のコードでは、最小 API エンドポイント /divide と /squareroot は、エラー入力時に予期されるカスタム問題の応答を返します。
API コントローラー エンドポイントは、カスタムの問題の応答ではなく、エラー入力で既定の問題の応答を返します。 既定の問題応答が返されるのは、 が呼び出される前に API コントローラーが応答ストリームに IProblemDetailsService.WriteAsync を書き込み、その後、応答が再度 書き込まれない ためです。
次の ValuesController は BadRequestResult を返します。これは、応答ストリームに書き込むため、カスタムの問題の応答が返されるのを回避します。
次の Values3Controller は ControllerBase.Problem を返すため、予期されるカスタム問題の結果が返されます。
例外に対する ProblemDetails ペイロードを生成する
次のアプリを考えてみましょう。
非開発環境では、例外が発生した場合、以下が、クライアントに返される標準の ProblemDetails 応答 です。
ほとんどのアプリでは、例外に必要なコードは上記ですべてです。 ただし、次のセクションでは、より詳細な問題の応答を取得する方法を示します。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使用すると、エラーにアクセスし、 IProblemDetailsService.WriteAsync を使用して問題の詳細の応答を書き込むことができます。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
問題の詳細を生成する別の方法としては、例外とクライアント エラーを問題の詳細にマップするために使用できるサードパーティの NuGet パッケージ Hellang.Middleware.ProblemDetails を使います。
サンプル コードを表示またはダウンロード します ( ダウンロード方法 )。
Azure App Service および IIS での ASP.NET Core のトラブルシューティング
ASP.NET Core を使用した Azure App Service および IIS の一般的なエラーのトラブルシューティング
ASP.NET Core API のエラーを処理する
著者: Tom Dykstra
この記事では、ASP.NET Core Web アプリでエラーを処理するための一般的な手法について取り上げます。 「 ASP.NET Core API でのエラーの処理 」も参照してください。
" 開発者例外ページ " には、未処理の要求の例外に関する詳細な情報が表示されます。 次の両方が当てはまる場合、ASP.NET Core アプリでは既定で開発者例外ページが有効になります。
Development 環境 で実行されています。
現在のテンプレート、つまり、 WebApplication.CreateBuilder で作成されたアプリ。 WebHost.CreateDefaultBuilder で作成されたアプリでは、 app.UseDeveloperExceptionPage で Configure を呼び出して開発者例外ページを有効にする必要があります。
開発者例外ページは、後続のミドルウェアでスローされた未処理の例外をキャッチできるように、ミドルウェア パイプラインの早い段階で実行されます。
アプリが Production 環境で実行されている場合は、詳細な例外情報をパブリックに表示しないでください。 環境の構成の詳細については、「 ASP.NET Core ランタイム環境 」を参照してください。
開発者例外ページには、例外と要求に関する次の情報が含まれている場合があります。
クエリ文字列のパラメーター (ある場合)
開発者例外ページで何らかの情報が提供されるとは限りません。 完全なエラー情報については、 ログ記録 に関するページを参照してください。
Production 環境 のカスタム エラー処理ページを構成するには、 UseExceptionHandler を呼び出します。 この例外処理ミドルウェアは、次のことを行います。
未処理の例外をキャッチしてログに記録します。
指定されたパスを使用して、別のパイプラインで要求を再実行します。 応答が始まっていた場合、要求は再実行されません。 テンプレートによって生成されたコードは、 /Error パスを使用して要求を再実行します。
代替パイプラインが別の例外をスローした場合、例外処理ミドルウェアは元の例外を再スローします。
このミドルウェアは要求パイプラインを再実行できるため:
ミドルウェアは、同じ要求での再入を処理する必要があります。 これは通常、 _next を呼び出した後で状態をクリーンアップすること、またはやり直しを避けるため処理を HttpContext にキャッシュすることを意味します。 要求本文を処理するときは、これはフォーム リーダーのような結果をバッファーまたはキャッシュすることを意味します。
テンプレートで使われる UseExceptionHandler(IApplicationBuilder, String) オーバーロードの場合、要求パスのみが変更され、ルート データはクリアされます。 ヘッダー、メソッド、項目などの要求データは、すべてそのまま再利用されます。
スコープ付きサービスは同じままです。
次の例では、 UseExceptionHandler は、 Development 以外の環境で例外処理ミドルウェアを追加します。
Razor Pages アプリのテンプレートには、エラー ページ ( .cshtml ) と PageModel クラス ( ErrorModel ) が Pages フォルダー内に用意されています。 MVC アプリの場合、プロジェクト テンプレートには、 Error コントローラー用の Home アクション メソッドとエラー ビューが含まれています。
例外処理ミドルウェアでは、" 元の " HTTP メソッドを使用して要求が再実行されます。 エラー ハンドラーのエンドポイントが特定の HTTP メソッドのセットに制限されている場合は、それらの HTTP メソッドに対してのみ実行されます。 たとえば、 [HttpGet] 属性を使用する MVC コントローラーのアクションは、GET 要求に対してのみ実行されます。 " すべての " 要求がカスタム エラー処理ページに到達するようにするために、それらを特定の HTTP メソッドのセットに制限しないでください。
元の HTTP メソッドに応じて例外を異なる方法で処理するには:
Razor Pages の場合は、複数のハンドラー メソッドを作成します。 たとえば、GET 例外を処理するために OnGet を使用し、POST 例外を処理するために OnPost を使用します。
MVC の場合は、複数のアクションに HTTP 動詞属性を適用します。 たとえば、GET 例外を処理するために [HttpGet] を使用し、POST 例外を処理するために [HttpPost] を使用します。
認証されていないユーザーがカスタム エラー処理ページを表示できるようにするには、匿名アクセスがサポートされるようにします。
エラー ハンドラーで例外や元の要求パスにアクセスするには、 IExceptionHandlerPathFeature を使います。 次の例では、 IExceptionHandlerPathFeature を使用して、スローされた例外に関する詳細を取得しています。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使うと、応答を返す前にエラーにアクセスできます。
次のコードは、例外処理にラムダを使用しています。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
IExceptionHandler
IExceptionHandler は、既知の例外を一元的に処理するためのコールバックを開発者に提供するインターフェイスです。
IExceptionHandler の実装は、 IServiceCollection.AddExceptionHandler<T> を呼び出すことで登録されます。 IExceptionHandler インスタンスの有効期間はシングルトンです。 複数の実装を追加することが可能で、登録された順序で呼び出されます。
IExceptionHandler 実装を登録するだけでは不十分です。 登録されたハンドラーは例外処理ミドルウェアによって呼び出されるため、アプリは UseExceptionHandler を呼び出してそのミドルウェアを追加する必要もあります。 UseExceptionHandler が呼び出されない場合、登録済みの IExceptionHandler 実装は呼び出されません。
例外処理ミドルウェアは、登録された例外ハンドラーを順番に反復処理し、例外が処理されたことを示す true から TryHandleAsync を返します。 例外ハンドラーが例外を処理する場合は、 true を返して処理を停止できます。 例外ハンドラーによって例外が処理されない場合、ミドルウェアの既定の動作とオプションに制御がフォールバックされます。
.NET 8 と .NET 9 では、例外処理ミドルウェアは例外をログに記録し、 IExceptionHandler 実装が TryHandleAsync から true を返した場合でもメトリックを出力します。 ハンドラーが独自のログ記録を行う場合、例外は 2 回記録されます。1 回は Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware カテゴリの下に 1 回、ハンドラーのカテゴリの下に 1 回記録されます。 ハンドラーからのみログに記録するには、構成でミドルウェア カテゴリを除外します。
.NET 10 以降では、処理された例外の診断は既定で抑制されます。 SuppressDiagnosticsCallback を 参照してください。
次の例は IExceptionHandler の実装を示しています。
次の例は、依存関係の挿入用に IExceptionHandler 実装を登録し、それを呼び出す例外処理ミドルウェアを追加する方法を示しています。
IExceptionHandler を使用する際に UseExceptionHandler を構成する
例外処理ミドルウェアには、 IExceptionHandler で処理されない例外に対するフォールバック処理が必要です。 何も構成されていない場合、引数なしで app.UseExceptionHandler() を呼び出すと、起動時にスローされます。
System.InvalidOperationException: An error occurred when configuring the exception handler middleware. Either the 'ExceptionHandlingPath' or the 'ExceptionHandler' property must be set in 'UseExceptionHandler()'.
要件を満たすには、次のいずれかを使用します。
エラー パスを指定します。 app.UseExceptionHandler("/Error");
問題の詳細を有効にする: builder.Services.AddProblemDetails(); を呼び出してから app.UseExceptionHandler();
フォールバック ハンドラーを指定します。 app.UseExceptionHandler(exceptionHandlerApp => { ... });
IExceptionHandler の実装は、これらすべてのケースで引き続き最初に実行されます。 構成されたパス、問題の詳細の応答、またはフォールバック ハンドラーは、すべての TryHandleAsync が false を返す場合にのみ使用されます。
IExceptionHandler が応答を記述したり状態コードを設定したりせずに true を返した場合、応答は 404 Not Found になり、ミドルウェア ログが記録されます。
The exception handler configured on ExceptionHandlerOptions produced a 404 status response.
true を返す IExceptionHandler は、状態コードを含む完全な応答を記述する必要があります。 たとえば、 httpContext.Response.StatusCode 設定して本文を記述したり、 IProblemDetailsService.TryWriteAsync を呼び出したりします。 404 応答が意図的な場合は、 AllowStatusCode404Response を true に設定します。
上記のコードが Development 環境で実行される場合:
例外を処理するために CustomExceptionHandler がまず呼び出されます。
例外をログに記録した後、 TryHandleAsync メソッドは false を返します。そのため、 開発者例外ページ が表示されます。
例外を処理するために CustomExceptionHandler がまず呼び出されます。
例外をログに記録した後、 TryHandleAsync メソッドは false を返します。そのため、 /Error ページ が表示されます。
TryHandleAsync が代わりに true を返す場合:
残りの IExceptionHandler 実装は呼び出されません。
UseExceptionHandler で構成された例外ハンドラー のページ、パス、またはラムダは使用されません。 ハンドラーは、応答全体を書き込む役割を担います。
UseStatusCodePages
ASP.NET Core アプリでは、既定で、" 404 - 見つかりません " などの HTTP エラー状態コードの状態コード ページが表示されません。 アプリで、本文のない HTTP 400 から 599 のエラー状態コードが設定されると、状態コードと空の応答本文が返されます。 一般的なエラー状態コード用に既定のテキスト専用ハンドラーを有効にするには、 UseStatusCodePages で Program.cs を呼び出します。
要求処理ミドルウェアの前に UseStatusCodePages を呼び出します。 たとえば、静的ファイル ミドルウェアとエンドポイント ミドルウェアの前に UseStatusCodePages を呼び出します。
UseStatusCodePages を使用しない場合、エンドポイントなしで URL に移動すると、エンドポイントが見つからないことを示すブラウザー依存のエラー メッセージが返されます。 UseStatusCodePages が呼び出されると、ブラウザーにより次の応答が返されます。
UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
状態コード ページのミドルウェアは例外をキャッチ しません 。 カスタム エラー処理ページを提供するには、 例外ハンドラー ページ を使用します。
書式設定文字列での UseStatusCodePages
応答の内容の種類とテキストをカスタマイズするには、内容の種類と書式文字列を受け取る UseStatusCodePages のオーバーロードを使います。
上記のコードでは、 {0} はエラー コードのプレースホルダーです。
書式指定文字列を含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
ラムダでの UseStatusCodePages
カスタム エラー処理と応答書き込みコードを指定するには、ラムダ式を受け取る UseStatusCodePages のオーバーロードを使います。
ラムダを含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects 拡張メソッド:
クライアントに 302 - Found 状態コードを送信します。
URL テンプレートで指定されているエラー処理エンドポイントにクライアントをリダイレクトします。 エラー処理エンドポイントには、通常、エラー情報が表示され、HTTP 200 が返されます。
前のコードに示されているように、URL テンプレートには状態コード用の {0} プレースホルダーを含めることができます。 URL テンプレートが ~ (チルダ) で始まっている場合、 ~ はアプリの PathBase に置き換えられます。 アプリでエンドポイントを指定するときに、そのエンドポイントの MVC ビューまたは Razor ページを作成します。
この方法は、次のようなアプリで一般的に使用されます。
クライアントを別のエンドポイントにリダイレクトする必要がある場合 (通常は、別のアプリがエラーを処理する場合)。 Web アプリの場合は、クライアントのブラウザーのアドレス バーにリダイレクトされたエンドポイントが反映されます。
元のステータス コードを保持して最初のリダイレクト応答で返すべきではない。
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute 拡張メソッド:
代替パスを使用して要求パイプラインを再実行することで、応答本文を生成します。
パイプラインの再実行前または再実行後に状態コードを変更しません。
新しいパイプラインでは状態コードが完全に制御されるため、新しいパイプラインの実行によって応答の状態コードが変更される可能性があります。 新しいパイプラインで状態コードが変更されない場合、元の状態コードがクライアントに送信されます。
アプリ内でエンドポイントが指定されている場合は、そのエンドポイントの MVC ビューまたは Razor ページを作成します。
この方法は、アプリで次のことを行う必要がある場合によく使用されます。
別のエンドポイントにリダイレクトすることなく要求を処理する。 Web アプリの場合は、クライアントのブラウザーのアドレス バーに、初めに要求されていたエンドポイントが反映されます。
元の状態コードを保持し、応答で返す。
URL テンプレートは / で始まる必要があります。このテンプレートには、状態コード用のプレースホルダー {0} を含めることができます。 状態コードをクエリ文字列パラメーターとして渡すには、2 番目の引数を UseStatusCodePagesWithReExecute に渡します。 例えば次が挙げられます。
次の例で示すように、エラーを処理するエンドポイントでは、エラーを生成した元の URL を取得できます。
このミドルウェアは要求パイプラインを再実行できるため:
ミドルウェアは、同じ要求での再入を処理する必要があります。 これは通常、 _next を呼び出した後で状態をクリーンアップすること、またはやり直しを避けるため処理を HttpContext にキャッシュすることを意味します。 要求本文を処理するときは、これはフォーム リーダーのような結果をバッファーまたはキャッシュすることを意味します。
スコープ付きサービスは同じままです。
状態コード ページを無効にする
MVC コントローラーまたはアクション メソッドの状態コード ページを無効にするには、 [SkipStatusCodePages] 属性を使用します。
Razor Pages ハンドラー メソッドまたは MVC コントローラーの特定の要求に対して状態コード ページを無効にするには、 IStatusCodePagesFeature を使用します。
例外処理ページのコードが例外をスローすることもあります。 運用環境のエラー ページは十分にテストし、それ自体から例外がスローされないように特に注意する必要があります。
応答のヘッダーが送信された後は、次のようになります。
アプリで応答の状態コードを変更できません。
📥 下载地址(文章中间)
すべての例外ページやハンドラーを実行できません。 応答は完了している必要があります。あるいは、接続が中止となっている必要があります。
アプリ内の例外処理ロジックに加えて、 HTTP サーバーの実装 でも一部の例外を処理できます。 応答ヘッダーの送信前にサーバーで例外がキャッチされると、サーバーによって " 500 - Internal Server Error " 応答が応答本文なしで送信されます。 応答ヘッダーの送信後にサーバーで例外がキャッチされた場合、サーバーは接続を閉じます。 アプリで処理されない要求はサーバーで処理されます。 サーバーが要求を処理しているときに発生した例外は、すべてサーバーの例外処理によって処理されます。 この動作は、アプリのカスタム エラー ページ、例外処理ミドルウェア、およびフィルターから影響を受けません。
アプリの起動中に起こる例外はホスティング層だけが処理できます。 起動時のエラーをキャプチャ したり、 詳細なエラーをキャプチャ したりするように、ホストを構成することができます。
ホスティング レイヤーでは、ホスト アドレス/ポート バインド後にエラーが発生した場合にのみ、キャプチャされた起動時エラーに対するエラー ページを表示できます。 バインドが失敗した場合は、次のようになります。
ホスティング レイヤーにより重大な例外がログに記録されます。
dotnet プロセスがクラッシュします。
HTTP サーバーが Kestrel のときは、エラー ページは表示されません。
IIS (または Azure App Service) または IIS Express 上で実行している場合、プロセスを開始できなければ、 ASP.NET Core モジュール から " 502.5 - 処理エラー " が返されます。 詳細については、「 Azure App Service および IIS での ASP.NET Core のトラブルシューティング 」を参照してください。
データベース開発者ページ例外フィルター AddDatabaseDeveloperPageExceptionFilter では、Entity Framework Core の移行を使って解決できるデータベース関連の例外がキャプチャされます。 これらの例外が発生すると、問題が解決する可能性のあるアクションの詳細を含む HTML 応答が生成されます。 このページは、 Development 環境でのみ有効になります。 次のコードでは、データベース開発者ページの例外フィルターを追加しています。
MVC アプリでは、例外フィルターをグローバルに、またはコントローラーやアクションの単位で構成できます。 Razor Pages アプリでは、グローバルに、またはページ モデルの単位で構成できます。 このようなフィルターは、コントローラー アクションや別のフィルターの実行中に発生する未処理の例外を処理します。 詳細については、「 ASP.NET Core フィルター 」を参照してください。
例外フィルターは、MVC アクション内で発生する例外をトラップする場合には便利ですが、組み込みの 例外処理ミドルウェア UseExceptionHandler ほど柔軟ではありません。 選択された MVC アクションに応じて異なる方法でエラー処理を実行する必要がある場合を除き、 UseExceptionHandler を使用することをお勧めします。
モデル状態エラーを処理する方法については、 モデル バインド および モデルの検証 に関する記事をご覧ください。
問題の詳細 は、HTTP API エラーを記述する唯一の応答形式ではありませんが、一般的に HTTP API のエラーを報告するために使用されます。
問題の詳細サービスは、 IProblemDetailsService インターフェイスを実装し、これにより、ASP.NET Core での問題の詳細の作成がサポートされます。 AddProblemDetails(IServiceCollection) の IServiceCollection 拡張メソッドは、既定の IProblemDetailsService 実装を登録します。
ASP.NET Core アプリでは、次のミドルウェアによって、 AddProblemDetails が呼び出されたときに問題の詳細 HTTP 応答が生成されます。ただし、 Accept 要求 HTTP ヘッダー に、登録された IProblemDetailsWriter (既定値: application/json ) によってサポートされるいずれかのコンテンツ タイプが含まれていない場合を除きます。
ExceptionHandlerMiddleware : カスタム ハンドラーが定義されていない場合に、問題の詳細の応答を生成します。
StatusCodePagesMiddleware : 既定で問題の詳細の応答を生成します。
DeveloperExceptionPageMiddleware : 開発中に Accept 要求 HTTP ヘッダーに text/html が含まれていない場合に、問題の詳細応答を生成します。
次のコードは、" 本文コンテンツがまだ含まれていない " すべての HTTP クライアントおよびサーバー エラー応答に対して問題の詳細の応答を生成するようにアプリを構成します。
次のセクションでは、問題の詳細の応答の本文をカスタマイズする方法を示します。
ProblemDetails の自動作成は、次のどのオプションでもカスタマイズできます。
ProblemDetailsOptions.CustomizeProblemDetails を使用します
カスタム IProblemDetailsWriter を使用する
ミドルウェアで IProblemDetailsService を呼び出す
CustomizeProblemDetails 操作
生成された問題の詳細は CustomizeProblemDetails を使用してカスタマイズでき、カスタマイズはすべての自動生成された問題の詳細に適用されます。
次のコードは ProblemDetailsOptions を使用して CustomizeProblemDetails を設定します。
たとえば、 HTTP Status 400 Bad Request エンドポイントの結果により、次の問題の詳細の応答本文が生成されます。
カスタム IProblemDetailsWriter
高度なカスタマイズのために IProblemDetailsWriter の実装を作成できます。
注: カスタムの IProblemDetailsWriter を使う場合は、 IProblemDetailsWriter 、 AddRazorPages 、 AddControllers 、または AddControllersWithViews を呼び出す前にカスタムの AddMvc を登録する必要があります。
ProblemDetailsOptions を CustomizeProblemDetails と共に使用する別の方法として、ミドルウェアで ProblemDetails を設定します。 問題の詳細の応答は、 IProblemDetailsService.WriteAsync を呼び出すことによって書き込むことができます。
前のコードでは、最小 API エンドポイント /divide と /squareroot は、エラー入力時に予期されるカスタム問題の応答を返します。
API コントローラー エンドポイントは、カスタムの問題の応答ではなく、エラー入力で既定の問題の応答を返します。 既定の問題応答が返されるのは、 が呼び出される前に API コントローラーが応答ストリームに IProblemDetailsService.WriteAsync を書き込み、その後、応答が再度 書き込まれない ためです。
次の ValuesController は BadRequestResult を返します。これは、応答ストリームに書き込むため、カスタムの問題の応答が返されるのを回避します。
次の Values3Controller は ControllerBase.Problem を返すため、予期されるカスタム問題の結果が返されます。
例外に対する ProblemDetails ペイロードを生成する
次のアプリを考えてみましょう。
非開発環境では、例外が発生した場合、以下が、クライアントに返される標準の ProblemDetails 応答 です。
ほとんどのアプリでは、例外に必要なコードは上記ですべてです。 ただし、次のセクションでは、より詳細な問題の応答を取得する方法を示します。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使用すると、エラーにアクセスし、 IProblemDetailsService.WriteAsync を使用して問題の詳細の応答を書き込むことができます。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
問題の詳細を生成する別の方法としては、例外とクライアント エラーを問題の詳細にマップするために使用できるサードパーティの NuGet パッケージ Hellang.Middleware.ProblemDetails を使います。
サンプル コードを表示またはダウンロード します ( ダウンロード方法 )。
Azure App Service および IIS での ASP.NET Core のトラブルシューティング
ASP.NET Core を使用した Azure App Service および IIS の一般的なエラーのトラブルシューティング
ASP.NET Core API のエラーを処理する
ASP.NET Core API のエラーを処理します 。
著者: Tom Dykstra
この記事では、ASP.NET Core Web アプリでエラーを処理するための一般的な手法について取り上げます。 「 ASP.NET Core API でのエラーの処理 」も参照してください。
" 開発者例外ページ " には、未処理の要求の例外に関する詳細な情報が表示されます。 次の両方が当てはまる場合、ASP.NET Core アプリでは既定で開発者例外ページが有効になります。
Development 環境 で実行されています。
現在のテンプレート、つまり、 WebApplication.CreateBuilder で作成されたアプリ。 WebHost.CreateDefaultBuilder で作成されたアプリでは、 app.UseDeveloperExceptionPage で Configure を呼び出して開発者例外ページを有効にする必要があります。
開発者例外ページは、後続のミドルウェアでスローされた未処理の例外をキャッチできるように、ミドルウェア パイプラインの早い段階で実行されます。
アプリが Production 環境で実行されている場合は、詳細な例外情報をパブリックに表示しないでください。 環境の構成の詳細については、「 ASP.NET Core ランタイム環境 」を参照してください。
開発者例外ページには、例外と要求に関する次の情報が含まれている場合があります。
クエリ文字列のパラメーター (ある場合)
開発者例外ページで何らかの情報が提供されるとは限りません。 完全なエラー情報については、 ログ記録 に関するページを参照してください。
Production 環境 のカスタム エラー処理ページを構成するには、 UseExceptionHandler を呼び出します。 この例外処理ミドルウェアは、次のことを行います。
未処理の例外をキャッチしてログに記録します。
指定されたパスを使用して、別のパイプラインで要求を再実行します。 応答が始まっていた場合、要求は再実行されません。 テンプレートによって生成されたコードは、 /Error パスを使用して要求を再実行します。
代替パイプラインが別の例外をスローした場合、例外処理ミドルウェアは元の例外を再スローします。
このミドルウェアは要求パイプラインを再実行できるため:
ミドルウェアは、同じ要求での再入を処理する必要があります。 これは通常、 _next を呼び出した後で状態をクリーンアップすること、またはやり直しを避けるため処理を HttpContext にキャッシュすることを意味します。 要求本文を処理するときは、これはフォーム リーダーのような結果をバッファーまたはキャッシュすることを意味します。
テンプレートで使われる UseExceptionHandler(IApplicationBuilder, String) オーバーロードの場合、要求パスのみが変更され、ルート データはクリアされます。 ヘッダー、メソッド、項目などの要求データは、すべてそのまま再利用されます。
スコープ付きサービスは同じままです。
次の例では、 UseExceptionHandler は、 Development 以外の環境で例外処理ミドルウェアを追加します。
Razor Pages アプリのテンプレートには、エラー ページ ( .cshtml ) と PageModel クラス ( ErrorModel ) が Pages フォルダー内に用意されています。 MVC アプリの場合、プロジェクト テンプレートには、 Error コントローラー用の Home アクション メソッドとエラー ビューが含まれています。
例外処理ミドルウェアでは、" 元の " HTTP メソッドを使用して要求が再実行されます。 エラー ハンドラーのエンドポイントが特定の HTTP メソッドのセットに制限されている場合は、それらの HTTP メソッドに対してのみ実行されます。 たとえば、 [HttpGet] 属性を使用する MVC コントローラーのアクションは、GET 要求に対してのみ実行されます。 " すべての " 要求がカスタム エラー処理ページに到達するようにするために、それらを特定の HTTP メソッドのセットに制限しないでください。
元の HTTP メソッドに応じて例外を異なる方法で処理するには:
Razor Pages の場合は、複数のハンドラー メソッドを作成します。 たとえば、GET 例外を処理するために OnGet を使用し、POST 例外を処理するために OnPost を使用します。
MVC の場合は、複数のアクションに HTTP 動詞属性を適用します。 たとえば、GET 例外を処理するために [HttpGet] を使用し、POST 例外を処理するために [HttpPost] を使用します。
認証されていないユーザーがカスタム エラー処理ページを表示できるようにするには、匿名アクセスがサポートされるようにします。
エラー ハンドラーで例外や元の要求パスにアクセスするには、 IExceptionHandlerPathFeature を使います。 次の例では、 IExceptionHandlerPathFeature を使用して、スローされた例外に関する詳細を取得しています。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使うと、応答を返す前にエラーにアクセスできます。
次のコードは、例外処理にラムダを使用しています。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
UseStatusCodePages
ASP.NET Core アプリでは、既定で、" 404 - 見つかりません " などの HTTP エラー状態コードの状態コード ページが表示されません。 アプリで、本文のない HTTP 400 から 599 のエラー状態コードが設定されると、状態コードと空の応答本文が返されます。 一般的なエラー状態コード用に既定のテキスト専用ハンドラーを有効にするには、 UseStatusCodePages で Program.cs を呼び出します。
要求処理ミドルウェアの前に UseStatusCodePages を呼び出します。 たとえば、静的ファイル ミドルウェアとエンドポイント ミドルウェアの前に UseStatusCodePages を呼び出します。
UseStatusCodePages を使用しない場合、エンドポイントなしで URL に移動すると、エンドポイントが見つからないことを示すブラウザー依存のエラー メッセージが返されます。 UseStatusCodePages が呼び出されると、ブラウザーにより次の応答が返されます。
UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
状態コード ページのミドルウェアは例外をキャッチ しません 。 カスタム エラー処理ページを提供するには、 例外ハンドラー ページ を使用します。
書式設定文字列での UseStatusCodePages
応答の内容の種類とテキストをカスタマイズするには、内容の種類と書式文字列を受け取る UseStatusCodePages のオーバーロードを使います。
上記のコードでは、 {0} はエラー コードのプレースホルダーです。
書式指定文字列を含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
ラムダでの UseStatusCodePages
カスタム エラー処理と応答書き込みコードを指定するには、ラムダ式を受け取る UseStatusCodePages のオーバーロードを使います。
ラムダを含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects 拡張メソッド:
クライアントに 302 - Found 状態コードを送信します。
URL テンプレートで指定されているエラー処理エンドポイントにクライアントをリダイレクトします。 エラー処理エンドポイントには、通常、エラー情報が表示され、HTTP 200 が返されます。
前のコードに示されているように、URL テンプレートには状態コード用の {0} プレースホルダーを含めることができます。 URL テンプレートが ~ (チルダ) で始まっている場合、 ~ はアプリの PathBase に置き換えられます。 アプリでエンドポイントを指定するときに、そのエンドポイントの MVC ビューまたは Razor ページを作成します。
この方法は、次のようなアプリで一般的に使用されます。
クライアントを別のエンドポイントにリダイレクトする必要がある場合 (通常は、別のアプリがエラーを処理する場合)。 Web アプリの場合は、クライアントのブラウザーのアドレス バーにリダイレクトされたエンドポイントが反映されます。
元のステータス コードを保持して最初のリダイレクト応答で返すべきではない。
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute 拡張メソッド:
代替パスを使用して要求パイプラインを再実行することで、応答本文を生成します。
パイプラインの再実行前または再実行後に状態コードを変更しません。
新しいパイプラインでは状態コードが完全に制御されるため、新しいパイプラインの実行によって応答の状態コードが変更される可能性があります。 新しいパイプラインで状態コードが変更されない場合、元の状態コードがクライアントに送信されます。
アプリ内でエンドポイントが指定されている場合は、そのエンドポイントの MVC ビューまたは Razor ページを作成します。
この方法は、アプリで次のことを行う必要がある場合によく使用されます。
別のエンドポイントにリダイレクトすることなく要求を処理する。 Web アプリの場合は、クライアントのブラウザーのアドレス バーに、初めに要求されていたエンドポイントが反映されます。
元の状態コードを保持し、応答で返す。
URL テンプレートは / で始まる必要があります。このテンプレートには、状態コード用のプレースホルダー {0} を含めることができます。 状態コードをクエリ文字列パラメーターとして渡すには、2 番目の引数を UseStatusCodePagesWithReExecute に渡します。 例えば次が挙げられます。
次の例で示すように、エラーを処理するエンドポイントでは、エラーを生成した元の URL を取得できます。
このミドルウェアは要求パイプラインを再実行できるため:
ミドルウェアは、同じ要求での再入を処理する必要があります。 これは通常、 _next を呼び出した後で状態をクリーンアップすること、またはやり直しを避けるため処理を HttpContext にキャッシュすることを意味します。 要求本文を処理するときは、これはフォーム リーダーのような結果をバッファーまたはキャッシュすることを意味します。
スコープ付きサービスは同じままです。
状態コード ページを無効にする
MVC コントローラーまたはアクション メソッドの状態コード ページを無効にするには、 [SkipStatusCodePages] 属性を使用します。
Razor Pages ハンドラー メソッドまたは MVC コントローラーの特定の要求に対して状態コード ページを無効にするには、 IStatusCodePagesFeature を使用します。
例外処理ページのコードが例外をスローすることもあります。 運用環境のエラー ページは十分にテストし、それ自体から例外がスローされないように特に注意する必要があります。
応答のヘッダーが送信された後は、次のようになります。
アプリで応答の状態コードを変更できません。
すべての例外ページやハンドラーを実行できません。 応答は完了している必要があります。あるいは、接続が中止となっている必要があります。
アプリ内の例外処理ロジックに加えて、 HTTP サーバーの実装 でも一部の例外を処理できます。 応答ヘッダーの送信前にサーバーで例外がキャッチされると、サーバーによって " 500 - Internal Server Error " 応答が応答本文なしで送信されます。 応答ヘッダーの送信後にサーバーで例外がキャッチされた場合、サーバーは接続を閉じます。 アプリで処理されない要求はサーバーで処理されます。 サーバーが要求を処理しているときに発生した例外は、すべてサーバーの例外処理によって処理されます。 この動作は、アプリのカスタム エラー ページ、例外処理ミドルウェア、およびフィルターから影響を受けません。
アプリの起動中に起こる例外はホスティング層だけが処理できます。 起動時のエラーをキャプチャ したり、 詳細なエラーをキャプチャ したりするように、ホストを構成することができます。
ホスティング レイヤーでは、ホスト アドレス/ポート バインド後にエラーが発生した場合にのみ、キャプチャされた起動時エラーに対するエラー ページを表示できます。 バインドが失敗した場合は、次のようになります。
ホスティング レイヤーにより重大な例外がログに記録されます。
dotnet プロセスがクラッシュします。
HTTP サーバーが Kestrel のときは、エラー ページは表示されません。
IIS (または Azure App Service) または IIS Express 上で実行している場合、プロセスを開始できなければ、 ASP.NET Core モジュール から " 502.5 - 処理エラー " が返されます。 詳細については、「 Azure App Service および IIS での ASP.NET Core のトラブルシューティング 」を参照してください。
データベース開発者ページ例外フィルター AddDatabaseDeveloperPageExceptionFilter では、Entity Framework Core の移行を使って解決できるデータベース関連の例外がキャプチャされます。 これらの例外が発生すると、問題が解決する可能性のあるアクションの詳細を含む HTML 応答が生成されます。 このページは、 Development 環境でのみ有効になります。 次のコードでは、データベース開発者ページの例外フィルターを追加しています。
MVC アプリでは、例外フィルターをグローバルに、またはコントローラーやアクションの単位で構成できます。 Razor Pages アプリでは、グローバルに、またはページ モデルの単位で構成できます。 このようなフィルターは、コントローラー アクションや別のフィルターの実行中に発生する未処理の例外を処理します。 詳細については、「 ASP.NET Core フィルター 」を参照してください。
例外フィルターは、MVC アクション内で発生する例外をトラップする場合には便利ですが、組み込みの 例外処理ミドルウェア UseExceptionHandler ほど柔軟ではありません。 選択された MVC アクションに応じて異なる方法でエラー処理を実行する必要がある場合を除き、 UseExceptionHandler を使用することをお勧めします。
モデル状態エラーを処理する方法については、 モデル バインド および モデルの検証 に関する記事をご覧ください。
問題の詳細 は、HTTP API エラーを記述する唯一の応答形式ではありませんが、一般的に HTTP API のエラーを報告するために使用されます。
問題の詳細サービスは、 IProblemDetailsService インターフェイスを実装し、これにより、ASP.NET Core での問題の詳細の作成がサポートされます。 AddProblemDetails(IServiceCollection) の IServiceCollection 拡張メソッドは、既定の IProblemDetailsService 実装を登録します。
ASP.NET Core アプリでは、次のミドルウェアによって、 AddProblemDetails が呼び出されたときに問題の詳細 HTTP 応答が生成されます。ただし、 Accept 要求 HTTP ヘッダー に、登録された IProblemDetailsWriter (既定値: application/json ) によってサポートされるいずれかのコンテンツ タイプが含まれていない場合を除きます。
ExceptionHandlerMiddleware : カスタム ハンドラーが定義されていない場合に、問題の詳細の応答を生成します。
StatusCodePagesMiddleware : 既定で問題の詳細の応答を生成します。
DeveloperExceptionPageMiddleware : 開発中に Accept 要求 HTTP ヘッダーに text/html が含まれていない場合に、問題の詳細応答を生成します。
次のコードは、" 本文コンテンツがまだ含まれていない " すべての HTTP クライアントおよびサーバー エラー応答に対して問題の詳細の応答を生成するようにアプリを構成します。
次のセクションでは、問題の詳細の応答の本文をカスタマイズする方法を示します。
ProblemDetails の自動作成は、次のどのオプションでもカスタマイズできます。
ProblemDetailsOptions.CustomizeProblemDetails を使用します
カスタム IProblemDetailsWriter を使用する
ミドルウェアで IProblemDetailsService を呼び出す
CustomizeProblemDetails 操作
生成された問題の詳細は CustomizeProblemDetails を使用してカスタマイズでき、カスタマイズはすべての自動生成された問題の詳細に適用されます。
次のコードは ProblemDetailsOptions を使用して CustomizeProblemDetails を設定します。
たとえば、 HTTP Status 400 Bad Request エンドポイントの結果により、次の問題の詳細の応答本文が生成されます。
カスタム IProblemDetailsWriter
高度なカスタマイズのために IProblemDetailsWriter の実装を作成できます。
注: カスタムの IProblemDetailsWriter を使う場合は、 IProblemDetailsWriter 、 AddRazorPages 、 AddControllers 、または AddControllersWithViews を呼び出す前にカスタムの AddMvc を登録する必要があります。
ProblemDetailsOptions を CustomizeProblemDetails と共に使用する別の方法として、ミドルウェアで ProblemDetails を設定します。 問題の詳細の応答は、 IProblemDetailsService.WriteAsync を呼び出すことによって書き込むことができます。
前のコードでは、最小 API エンドポイント /divide と /squareroot は、エラー入力時に予期されるカスタム問題の応答を返します。
API コントローラー エンドポイントは、カスタムの問題の応答ではなく、エラー入力で既定の問題の応答を返します。 既定の問題応答が返されるのは、 が呼び出される前に API コントローラーが応答ストリームに IProblemDetailsService.WriteAsync を書き込み、その後、応答が再度 書き込まれない ためです。
次の ValuesController は BadRequestResult を返します。これは、応答ストリームに書き込むため、カスタムの問題の応答が返されるのを回避します。
次の Values3Controller は ControllerBase.Problem を返すため、予期されるカスタム問題の結果が返されます。
例外に対する ProblemDetails ペイロードを生成する
次のアプリを考えてみましょう。
非開発環境では、例外が発生した場合、以下が、クライアントに返される標準の ProblemDetails 応答 です。
ほとんどのアプリでは、例外に必要なコードは上記ですべてです。 ただし、次のセクションでは、より詳細な問題の応答を取得する方法を示します。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使用すると、エラーにアクセスし、 IProblemDetailsService.WriteAsync を使用して問題の詳細の応答を書き込むことができます。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
問題の詳細を生成する別の方法としては、例外とクライアント エラーを問題の詳細にマップするために使用できるサードパーティの NuGet パッケージ Hellang.Middleware.ProblemDetails を使います。
サンプル コードを表示またはダウンロード します ( ダウンロード方法 )。
Azure App Service および IIS での ASP.NET Core のトラブルシューティング
ASP.NET Core を使用した Azure App Service および IIS の一般的なエラーのトラブルシューティング
著者: Tom Dykstra
この記事では、ASP.NET Core Web アプリでエラーを処理するための一般的な手法について取り上げます。 Web API については、 ASP.NET Core API でエラーを処理する を参照してください。
" 開発者例外ページ " には、未処理の要求の例外に関する詳細な情報が表示されます。 次の両方が当てはまる場合、ASP.NET Core アプリでは既定で開発者例外ページが有効になります。
Development 環境 で実行されています。
現在のテンプレート、つまり、 WebApplication.CreateBuilder で作成されたアプリ。 WebHost.CreateDefaultBuilder で作成されたアプリでは、 app.UseDeveloperExceptionPage で Configure を呼び出して開発者例外ページを有効にする必要があります。
開発者例外ページは、後続のミドルウェアでスローされた未処理の例外をキャッチできるように、ミドルウェア パイプラインの早い段階で実行されます。
アプリが Production 環境で実行されている場合は、詳細な例外情報をパブリックに表示しないでください。 環境の構成の詳細については、「 ASP.NET Core ランタイム環境 」を参照してください。
開発者例外ページには、例外と要求に関する次の情報が含まれている場合があります。
クエリ文字列のパラメーター (ある場合)
開発者例外ページで何らかの情報が提供されるとは限りません。 完全なエラー情報については、 ログ記録 に関するページを参照してください。
Production 環境 のカスタム エラー処理ページを構成するには、 UseExceptionHandler を呼び出します。 この例外処理ミドルウェアは、次のことを行います。
未処理の例外をキャッチしてログに記録します。
指定されたパスを使用して、別のパイプラインで要求を再実行します。 応答が始まっていた場合、要求は再実行されません。 テンプレートによって生成されたコードは、 /Error パスを使用して要求を再実行します。
代替パイプラインが別の例外をスローした場合、例外処理ミドルウェアは元の例外を再スローします。
次の例では、 UseExceptionHandler は、 Development 以外の環境で例外処理ミドルウェアを追加します。
Razor Pages アプリのテンプレートには、エラー ページ ( .cshtml ) と PageModel クラス ( ErrorModel ) が Pages フォルダー内に用意されています。 MVC アプリの場合、プロジェクト テンプレートには、 Error コントローラー用の Home アクション メソッドとエラー ビューが含まれています。
例外処理ミドルウェアでは、" 元の " HTTP メソッドを使用して要求が再実行されます。 エラー ハンドラーのエンドポイントが特定の HTTP メソッドのセットに制限されている場合は、それらの HTTP メソッドに対してのみ実行されます。 たとえば、 [HttpGet] 属性を使用する MVC コントローラーのアクションは、GET 要求に対してのみ実行されます。 " すべての " 要求がカスタム エラー処理ページに到達するようにするために、それらを特定の HTTP メソッドのセットに制限しないでください。
元の HTTP メソッドに応じて例外を異なる方法で処理するには:
Razor Pages の場合は、複数のハンドラー メソッドを作成します。 たとえば、GET 例外を処理するために OnGet を使用し、POST 例外を処理するために OnPost を使用します。
MVC の場合は、複数のアクションに HTTP 動詞属性を適用します。 たとえば、GET 例外を処理するために [HttpGet] を使用し、POST 例外を処理するために [HttpPost] を使用します。
認証されていないユーザーがカスタム エラー処理ページを表示できるようにするには、匿名アクセスがサポートされるようにします。
エラー ハンドラーで例外や元の要求パスにアクセスするには、 IExceptionHandlerPathFeature を使います。 次の例では、 IExceptionHandlerPathFeature を使用して、スローされた例外に関する詳細を取得しています。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使うと、応答を返す前にエラーにアクセスできます。
次のコードは、例外処理にラムダを使用しています。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
UseStatusCodePages
ASP.NET Core アプリでは、既定で、" 404 - 見つかりません " などの HTTP エラー状態コードの状態コード ページが表示されません。 アプリで、本文のない HTTP 400 から 599 のエラー状態コードが設定されると、状態コードと空の応答本文が返されます。 一般的なエラー状態コード用に既定のテキスト専用ハンドラーを有効にするには、 UseStatusCodePages で Program.cs を呼び出します。
要求処理ミドルウェアの前に UseStatusCodePages を呼び出します。 たとえば、静的ファイル ミドルウェアとエンドポイント ミドルウェアの前に UseStatusCodePages を呼び出します。
UseStatusCodePages を使用しない場合、エンドポイントなしで URL に移動すると、エンドポイントが見つからないことを示すブラウザー依存のエラー メッセージが返されます。 UseStatusCodePages が呼び出されると、ブラウザーにより次の応答が返されます。
UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
状態コード ページのミドルウェアは例外をキャッチ しません 。 カスタム エラー処理ページを提供するには、 例外ハンドラー ページ を使用します。
書式設定文字列での UseStatusCodePages
応答の内容の種類とテキストをカスタマイズするには、内容の種類と書式文字列を受け取る UseStatusCodePages のオーバーロードを使います。
上記のコードでは、 {0} はエラー コードのプレースホルダーです。
書式指定文字列を含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
ラムダでの UseStatusCodePages
カスタム エラー処理と応答書き込みコードを指定するには、ラムダ式を受け取る UseStatusCodePages のオーバーロードを使います。
ラムダを含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects 拡張メソッド:
クライアントに 302 - Found 状態コードを送信します。
URL テンプレートで指定されているエラー処理エンドポイントにクライアントをリダイレクトします。 エラー処理エンドポイントには、通常、エラー情報が表示され、HTTP 200 が返されます。
前のコードに示されているように、URL テンプレートには状態コード用の {0} プレースホルダーを含めることができます。 URL テンプレートが ~ (チルダ) で始まっている場合、 ~ はアプリの PathBase に置き換えられます。 アプリでエンドポイントを指定するときに、そのエンドポイントの MVC ビューまたは Razor ページを作成します。
この方法は、次のようなアプリで一般的に使用されます。
クライアントを別のエンドポイントにリダイレクトする必要がある場合 (通常は、別のアプリがエラーを処理する場合)。 Web アプリの場合は、クライアントのブラウザーのアドレス バーにリダイレクトされたエンドポイントが反映されます。
元のステータス コードを保持して最初のリダイレクト応答で返すべきではない。
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute 拡張メソッド:
元の状態コードをクライアントに返します。
代替パスを使用して要求パイプラインを再実行することで、応答本文を生成します。
アプリ内でエンドポイントが指定されている場合は、そのエンドポイントの MVC ビューまたは Razor ページを作成します。
この方法は、アプリで次のことを行う必要がある場合によく使用されます。
別のエンドポイントにリダイレクトすることなく要求を処理する。 Web アプリの場合は、クライアントのブラウザーのアドレス バーに、初めに要求されていたエンドポイントが反映されます。
元の状態コードを保持し、応答で返す。
URL テンプレートは / で始まる必要があります。このテンプレートには、状態コード用のプレースホルダー {0} を含めることができます。 状態コードをクエリ文字列パラメーターとして渡すには、2 番目の引数を UseStatusCodePagesWithReExecute に渡します。 例えば次が挙げられます。
次の例で示すように、エラーを処理するエンドポイントでは、エラーを生成した元の URL を取得できます。
状態コード ページを無効にする
MVC コントローラーまたはアクション メソッドの状態コード ページを無効にするには、 [SkipStatusCodePages] 属性を使用します。
Razor Pages ハンドラー メソッドまたは MVC コントローラーの特定の要求に対して状態コード ページを無効にするには、 IStatusCodePagesFeature を使用します。
例外処理ページのコードが例外をスローすることもあります。 運用環境のエラー ページは十分にテストし、それ自体から例外がスローされないように特に注意する必要があります。
応答のヘッダーが送信された後は、次のようになります。
アプリで応答の状態コードを変更できません。
すべての例外ページやハンドラーを実行できません。 応答は完了している必要があります。あるいは、接続が中止となっている必要があります。
アプリ内の例外処理ロジックに加えて、 HTTP サーバーの実装 でも一部の例外を処理できます。 応答ヘッダーの送信前にサーバーで例外がキャッチされると、サーバーによって " 500 - Internal Server Error " 応答が応答本文なしで送信されます。 応答ヘッダーの送信後にサーバーで例外がキャッチされた場合、サーバーは接続を閉じます。 アプリで処理されない要求はサーバーで処理されます。 サーバーが要求を処理しているときに発生した例外は、すべてサーバーの例外処理によって処理されます。 この動作は、アプリのカスタム エラー ページ、例外処理ミドルウェア、およびフィルターから影響を受けません。
アプリの起動中に起こる例外はホスティング層だけが処理できます。 起動時のエラーをキャプチャ したり、 詳細なエラーをキャプチャ したりするように、ホストを構成することができます。
ホスティング レイヤーでは、ホスト アドレス/ポート バインド後にエラーが発生した場合にのみ、キャプチャされた起動時エラーに対するエラー ページを表示できます。 バインドが失敗した場合は、次のようになります。
ホスティング レイヤーにより重大な例外がログに記録されます。
dotnet プロセスがクラッシュします。
HTTP サーバーが Kestrel のときは、エラー ページは表示されません。
IIS (または Azure App Service) または IIS Express 上で実行している場合、プロセスを開始できなければ、 ASP.NET Core モジュール から " 502.5 - 処理エラー " が返されます。 詳細については、「 Azure App Service および IIS での ASP.NET Core のトラブルシューティング 」を参照してください。
データベース開発者ページ例外フィルター AddDatabaseDeveloperPageExceptionFilter では、Entity Framework Core の移行を使って解決できるデータベース関連の例外がキャプチャされます。 これらの例外が発生すると、問題が解決する可能性のあるアクションの詳細を含む HTML 応答が生成されます。 このページは、 Development 環境でのみ有効になります。 次のコードでは、データベース開発者ページの例外フィルターを追加しています。
MVC アプリでは、例外フィルターをグローバルに、またはコントローラーやアクションの単位で構成できます。 Razor Pages アプリでは、グローバルに、またはページ モデルの単位で構成できます。 このようなフィルターは、コントローラー アクションや別のフィルターの実行中に発生する未処理の例外を処理します。 詳細については、「 ASP.NET Core フィルター 」を参照してください。
例外フィルターは、MVC アクション内で発生する例外をトラップする場合には便利ですが、組み込みの 例外処理ミドルウェア UseExceptionHandler ほど柔軟ではありません。 選択された MVC アクションに応じて異なる方法でエラー処理を実行する必要がある場合を除き、 UseExceptionHandler を使用することをお勧めします。
モデル状態エラーを処理する方法については、 モデル バインド および モデルの検証 に関する記事をご覧ください。
サンプル コードを表示またはダウンロード します ( ダウンロード方法 )。
Azure App Service および IIS での ASP.NET Core のトラブルシューティング
ASP.NET Core を使用した Azure App Service および IIS の一般的なエラーのトラブルシューティング
作成者: Kirk Larkin 、 Tom Dykstra 、 Steve Smith
この記事では、ASP.NET Core Web アプリでエラーを処理するための一般的な手法について取り上げます。 Web API については、 ASP.NET Core API でエラーを処理する を参照してください。
サンプル コードを表示またはダウンロード します。 ( ダウンロード方法 。)F12 ブラウザー開発者ツールの [ネットワーク] タブは、サンプル アプリをテストする場合に便利です。
" 開発者例外ページ " には、未処理の要求の例外に関する詳細な情報が表示されます。 ASP.NET Core テンプレートにより、次のコードが生成されます。
上記の強調表示されたコードでは、アプリが Development 環境 で実行されているときに開発者例外ページが有効になります。
これらのテンプレートでは、後続のミドルウェアでスローされる未処理の例外をキャッチできるように、ミドルウェア パイプラインの早い段階に UseDeveloperExceptionPage を配置します。
上記のコードでは、アプリが 環境で実行されている場合 、開発者例外ページが有効になります。 アプリが Production 環境で実行されている場合は、詳細な例外情報をパブリックに表示しないでください。 環境の構成の詳細については、「 ASP.NET Core ランタイム環境 」を参照してください。
開発者例外ページには、例外と要求に関する次の情報が含まれている場合があります。
クエリ文字列のパラメーター (ある場合)
開発者例外ページで何らかの情報が提供されるとは限りません。 完全なエラー情報については、 ログ記録 に関するページを参照してください。
Production 環境 のカスタム エラー処理ページを構成するには、 UseExceptionHandler を呼び出します。 この例外処理ミドルウェアは、次のことを行います。
未処理の例外をキャッチしてログに記録します。
指定されたパスを使用して、別のパイプラインで要求を再実行します。 応答が始まっていた場合、要求は再実行されません。 テンプレートによって生成されたコードは、 /Error パスを使用して要求を再実行します。
代替パイプラインが別の例外をスローした場合、例外処理ミドルウェアは元の例外を再スローします。
次の例では、 UseExceptionHandler は、 Development 以外の環境で例外処理ミドルウェアを追加します。
Razor Pages アプリのテンプレートには、エラー ページ ( .cshtml ) と PageModel クラス ( ErrorModel ) が Pages フォルダー内に用意されています。 MVC アプリの場合、プロジェクト テンプレートには、 Error コントローラー用の Home アクション メソッドとエラー ビューが含まれています。
例外処理ミドルウェアでは、" 元の " HTTP メソッドを使用して要求が再実行されます。 エラー ハンドラーのエンドポイントが特定の HTTP メソッドのセットに制限されている場合は、それらの HTTP メソッドに対してのみ実行されます。 たとえば、 [HttpGet] 属性を使用する MVC コントローラーのアクションは、GET 要求に対してのみ実行されます。 " すべての " 要求がカスタム エラー処理ページに到達するようにするために、それらを特定の HTTP メソッドのセットに制限しないでください。
元の HTTP メソッドに応じて例外を異なる方法で処理するには:
Razor Pages の場合は、複数のハンドラー メソッドを作成します。 たとえば、GET 例外を処理するために OnGet を使用し、POST 例外を処理するために OnPost を使用します。
MVC の場合は、複数のアクションに HTTP 動詞属性を適用します。 たとえば、GET 例外を処理するために [HttpGet] を使用し、POST 例外を処理するために [HttpPost] を使用します。
認証されていないユーザーがカスタム エラー処理ページを表示できるようにするには、匿名アクセスがサポートされるようにします。
エラー ハンドラーで例外や元の要求パスにアクセスするには、 IExceptionHandlerPathFeature を使います。 次のコードは、ASP.NET Core テンプレートによって生成される既定の ExceptionMessage に Pages/Error.cshtml.cs を追加します。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
サンプル アプリ で例外をテストするには:
webBuilder.UseStartup<Startup>(); の Program.cs からコメントを削除します。
ホーム ページで [Trigger an exception](例外をトリガーする) を選択します。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使うと、応答を返す前にエラーにアクセスできます。
次のコードは、例外処理にラムダを使用しています。
IExceptionHandlerFeature または IExceptionHandlerPathFeature からの機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
サンプル アプリ で例外処理ラムダをテストするには:
webBuilder.UseStartup<StartupLambda>(); の Program.cs からコメントを削除します。
ホーム ページで [Trigger an exception](例外をトリガーする) を選択します。
UseStatusCodePages
ASP.NET Core アプリでは、既定で、" 404 - 見つかりません " などの HTTP エラー状態コードの状態コード ページが表示されません。 アプリで、本文のない HTTP 400 から 599 のエラー状態コードが設定されると、状態コードと空の応答本文が返されます。 状態コード ページを提供するには、状態コード ページ ミドルウェアを使用します。 一般的なエラー状態コード用に既定のテキスト専用ハンドラーを有効にするには、 UseStatusCodePages メソッドで Startup.Configure を呼び出します。
要求処理ミドルウェアの前に UseStatusCodePages を呼び出します。 たとえば、静的ファイル ミドルウェアとエンドポイント ミドルウェアの前に UseStatusCodePages を呼び出します。
UseStatusCodePages を使用しない場合、エンドポイントなしで URL に移動すると、エンドポイントが見つからないことを示すブラウザー依存のエラー メッセージが返されます。 たとえば、 Home/Privacy2 に移動します。 UseStatusCodePages が呼び出されると、ブラウザーにより次が返されます。
UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
UseStatusCodePages で をテストするには:
webBuilder.UseStartup<StartupUseStatusCodePages>(); の Program.cs からコメントを削除します。
ホーム ページにあるリンクを選択します。
状態コード ページのミドルウェアは例外をキャッチ しません 。 カスタム エラー処理ページを提供するには、 例外ハンドラー ページ を使用します。
書式設定文字列での UseStatusCodePages
応答の内容の種類とテキストをカスタマイズするには、内容の種類と書式文字列を受け取る UseStatusCodePages のオーバーロードを使います。
上記のコードでは、 {0} はエラー コードのプレースホルダーです。
書式指定文字列を含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
UseStatusCodePages で をテストするには、 webBuilder.UseStartup<StartupFormat>(); 内の Program.cs からコメントを削除します。
ラムダでの UseStatusCodePages
カスタム エラー処理と応答書き込みコードを指定するには、ラムダ式を受け取る UseStatusCodePages のオーバーロードを使います。
ラムダを含む UseStatusCodePages は、ユーザーにとって役に立たないメッセージを返すため、通常は、運用環境では使用されません。
UseStatusCodePages で をテストするには、 webBuilder.UseStartup<StartupStatusLambda>(); 内の Program.cs からコメントを削除します。
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects 拡張メソッド:
クライアントに 302 - Found 状態コードを送信します。
URL テンプレートで指定されているエラー処理エンドポイントにクライアントをリダイレクトします。 エラー処理エンドポイントには、通常、エラー情報が表示され、HTTP 200 が返されます。
前のコードに示されているように、URL テンプレートには状態コード用の {0} プレースホルダーを含めることができます。 URL テンプレートが ~ (チルダ) で始まっている場合、 ~ はアプリの PathBase に置き換えられます。 アプリでエンドポイントを指定するときに、そのエンドポイントの MVC ビューまたは Razor ページを作成します。 Razor Pages の例については、 サンプル アプリ にある Pages/MyStatusCode.cshtml をご覧ください。
この方法は、次のようなアプリで一般的に使用されます。
クライアントを別のエンドポイントにリダイレクトする必要がある場合 (通常は、別のアプリがエラーを処理する場合)。 Web アプリの場合は、クライアントのブラウザーのアドレス バーにリダイレクトされたエンドポイントが反映されます。
元のステータス コードを保持して最初のリダイレクト応答で返すべきではない。
UseStatusCodePages で をテストするには、 webBuilder.UseStartup<StartupSCredirect>(); 内の Program.cs からコメントを削除します。
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute 拡張メソッド:
元の状態コードをクライアントに返します。
代替パスを使用して要求パイプラインを再実行することで、応答本文を生成します。
アプリ内でエンドポイントが指定されている場合は、そのエンドポイントの MVC ビューまたは Razor ページを作成します。 UseStatusCodePagesWithReExecute の前に UseRouting が配置されていることを確認して、要求を状態ページに再ルーティングできるようにします。 Razor Pages の例については、 サンプル アプリ にある Pages/MyStatusCode2.cshtml をご覧ください。
この方法は、アプリで次のことを行う必要がある場合によく使用されます。
別のエンドポイントにリダイレクトすることなく要求を処理する。 Web アプリの場合は、クライアントのブラウザーのアドレス バーに、初めに要求されていたエンドポイントが反映されます。
元の状態コードを保持し、応答で返す。
URL とクエリ文字列のテンプレートには、状態コード用のプレースホルダー {0} を含めることができます。 URL テンプレートの先頭には、 / を付ける必要があります。
次の例で示すように、エラーを処理するエンドポイントでは、エラーを生成した元の URL を取得できます。
Razor Pages の例については、 サンプル アプリ にある Pages/MyStatusCode2.cshtml をご覧ください。
UseStatusCodePages で をテストするには、 webBuilder.UseStartup<StartupSCreX>(); 内の Program.cs からコメントを削除します。
状態コード ページを無効にする
MVC コントローラーまたはアクション メソッドの状態コード ページを無効にするには、 [SkipStatusCodePages] 属性を使用します。
Razor Pages ハンドラー メソッドまたは MVC コントローラーの特定の要求に対して状態コード ページを無効にするには、 IStatusCodePagesFeature を使用します。
例外処理ページのコードが例外をスローすることもあります。 運用環境のエラー ページは十分にテストし、それ自体から例外がスローされないように特に注意する必要があります。
応答のヘッダーが送信された後は、次のようになります。
アプリで応答の状態コードを変更できません。
すべての例外ページやハンドラーを実行できません。 応答は完了している必要があります。あるいは、接続が中止となっている必要があります。
アプリ内の例外処理ロジックに加えて、 HTTP サーバーの実装 でも一部の例外を処理できます。 応答ヘッダーの送信前にサーバーで例外がキャッチされると、サーバーによって " 500 - Internal Server Error " 応答が応答本文なしで送信されます。 応答ヘッダーの送信後にサーバーで例外がキャッチされた場合、サーバーは接続を閉じます。 アプリで処理されない要求はサーバーで処理されます。 サーバーが要求を処理しているときに発生した例外は、すべてサーバーの例外処理によって処理されます。 この動作は、アプリのカスタム エラー ページ、例外処理ミドルウェア、およびフィルターから影響を受けません。
アプリの起動中に起こる例外はホスティング層だけが処理できます。 起動時のエラーをキャプチャ したり、 詳細なエラーをキャプチャ したりするように、ホストを構成することができます。
ホスティング レイヤーでは、ホスト アドレス/ポート バインド後にエラーが発生した場合にのみ、キャプチャされた起動時エラーに対するエラー ページを表示できます。 バインドが失敗した場合は、次のようになります。
ホスティング レイヤーにより重大な例外がログに記録されます。
dotnet プロセスがクラッシュします。
HTTP サーバーが Kestrel のときは、エラー ページは表示されません。
IIS (または Azure App Service) または IIS Express 上で実行している場合、プロセスを開始できなければ、 ASP.NET Core モジュール から " 502.5 - 処理エラー " が返されます。 詳細については、「 Azure App Service および IIS での ASP.NET Core のトラブルシューティング 」を参照してください。
データベース開発者ページ例外フィルター AddDatabaseDeveloperPageExceptionFilter では、Entity Framework Core の移行を使って解決できるデータベース関連の例外がキャプチャされます。 これらの例外が発生すると、問題が解決する可能性のあるアクションの詳細を含む HTML 応答が生成されます。 このページは、 Development 環境でのみ有効になります。 次のコードは、個々のユーザー アカウントが指定されたときに、ASP.NET Core Razor Pages テンプレートによって生成されたものです。
MVC アプリでは、例外フィルターをグローバルに、またはコントローラーやアクションの単位で構成できます。 Razor Pages アプリでは、グローバルに、またはページ モデルの単位で構成できます。 このようなフィルターは、コントローラー アクションや別のフィルターの実行中に発生する未処理の例外を処理します。 詳細については、「 ASP.NET Core フィルター 」を参照してください。
例外フィルターは、MVC アクション内で発生する例外をトラップする場合には便利ですが、組み込みの 例外処理ミドルウェア UseExceptionHandler ほど柔軟ではありません。 選択された MVC アクションに応じて異なる方法でエラー処理を実行する必要がある場合を除き、 UseExceptionHandler を使用することをお勧めします。
モデル状態エラーを処理する方法については、 モデル バインド および モデルの検証 に関する記事をご覧ください。
Azure App Service および IIS での ASP.NET Core のトラブルシューティング
ASP.NET Core を使用した Azure App Service および IIS の一般的なエラーのトラブルシューティング
作成者: Tom Dykstra 、 Steve Smith
この記事では、ASP.NET Core Web アプリでエラーを処理するための一般的な手法について取り上げます。 Web API については、 ASP.NET Core API でエラーを処理する を参照してください。
サンプル コードを表示またはダウンロード します。 ( ダウンロード方法 。)
" 開発者例外ページ " には、要求の例外に関する詳細な情報が表示されます。 ASP.NET Core テンプレートにより、次のコードが生成されます。
上記のコードでは、アプリが Development 環境 で実行されているときに開発者例外ページを有効にします。
このテンプレートでは、後続のミドルウェアで例外をキャッチできるように、ミドルウェアの前に UseDeveloperExceptionPage が配置されます。
上記のコードでは、 アプリが Development 環境で実行されている場合にのみ 、開発者例外ページが有効になります。 アプリが運用環境で実行されている場合は、詳細な例外情報を公開しないようにしてください。 環境の構成の詳細については、「 ASP.NET Core ランタイム環境 」を参照してください。
開発者例外ページには、例外と要求に関する次の情報が含まれています。
クエリ文字列のパラメーター (ある場合)
Production 環境のカスタム エラー処理ページを構成するには、例外処理ミドルウェアを使用します。 ミドルウェア:
例外をキャッチしてログに記録します。
ページ用の、またはコントローラーが指定した別のパイプラインで、要求を再実行します。 応答が始まっていた場合、要求は再実行されません。 テンプレートによって生成されたコードは、 /Error への要求を再実行します。
次の例では、 UseExceptionHandler は、 Development 以外の環境で例外処理ミドルウェアを追加します。
Razor Pages アプリのテンプレートには、エラー ページ ( .cshtml ) と PageModel クラス ( ErrorModel ) が Pages フォルダー内に用意されています。 MVC アプリの場合、プロジェクト テンプレートには、Home コントローラーのエラー アクション メソッドとエラー ビューが含まれています。
HttpGet などの HTTP メソッド属性を使ってエラー ハンドラー アクション メソッドをマークしないでください。 明示的な動詞を使用すると、要求がメソッドに届かないことがあります。 認証されていないユーザーにエラー ビューが表示される場合は、メソッドへの匿名アクセスを許可します。
エラー ハンドラー コントローラーまたはページ内で例外や元の要求パスにアクセスするには、 IExceptionHandlerPathFeature を使います。
機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
上記の例外処理ページをトリガーするには、環境を運用に設定し、例外を強制します。
カスタム例外ハンドラー ページ の代わりになるのは、 UseExceptionHandler にラムダを提供することです。 ラムダを使うと、応答を返す前にエラーにアクセスできます。
例外処理にラムダを使う例を次に示します。
上記のコードでは await context.Response.WriteAsync(new string(' ', 512)); が追加されるため、Internet Explorer ブラウザーには IE のエラー メッセージではなく、このエラー メッセージが表示されます。 詳細については、 この GitHub issue を参照してください。
IExceptionHandlerFeature または IExceptionHandlerPathFeature からの機密性の高いエラー情報をクライアントに提供 しないでください 。 エラーの提供はセキュリティ上のリスクです。
サンプル アプリの で例外処理ラムダの結果を確認するには、 および プリプロセッサ ディレクティブを使用し、ホーム ページで例外 をトリガー 選択します。
UseStatusCodePages
ASP.NET Core アプリでは、既定で、" 404 - 見つかりません " などの HTTP 状態コードの状態コード ページが表示されません。 アプリでは、状態コードと空の応答本文が返されます。 状態コード ページを提供するには、状態コード ページ ミドルウェアを使用します。
そのミドルウェアは、 Microsoft.AspNetCore.Diagnostics パッケージによって使用可能になります。
一般的なエラー状態コード用に既定のテキスト専用ハンドラーを有効にするには、 UseStatusCodePages メソッドで Startup.Configure を呼び出します。
要求処理ミドルウェア (静的ファイル ミドルウェアや MVC ミドルウェアなど) の前に UseStatusCodePages を呼び出します。
UseStatusCodePages を使用しない場合、エンドポイントなしで URL に移動すると、エンドポイントが見つからないことを示すブラウザー依存のエラー メッセージが返されます。 たとえば、 Home/Privacy2 に移動します。 UseStatusCodePages が呼び出されると、ブラウザーにより次が返されます。
書式設定文字列での UseStatusCodePages
応答の内容の種類とテキストをカスタマイズするには、内容の種類と書式文字列を受け取る UseStatusCodePages のオーバーロードを使います。
ラムダでの UseStatusCodePages
カスタム エラー処理と応答書き込みコードを指定するには、ラムダ式を受け取る UseStatusCodePages のオーバーロードを使います。
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects 拡張メソッド:
クライアントに 302 - Found 状態コードを送信します。
URL テンプレートで指定された場所にクライアントをリダイレクトします。
次の例で示すように、URL テンプレートには状態コード用の {0} プレースホルダーを含めることができます。 URL テンプレートが ~ (チルダ) で始まっている場合、 ~ はアプリの PathBase に置き換えられます。 アプリ内でエンドポイントを指し示す場合は、そのエンドポイントの MVC ビューまたは Razor ページを作成します。 Razor Pages の例については、 Pages/StatusCode.cshtml の を参照してください。
この方法は、次のようなアプリで一般的に使用されます。
クライアントを別のエンドポイントにリダイレクトする必要がある場合 (通常は、別のアプリがエラーを処理する場合)。 Web アプリの場合は、クライアントのブラウザーのアドレス バーにリダイレクトされたエンドポイントが反映されます。
元のステータス コードを保持して最初のリダイレクト応答で返すべきではない。
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute 拡張メソッド:
元の状態コードをクライアントに返します。
代替パスを使用して要求パイプラインを再実行することで、応答本文を生成します。
アプリ内でエンドポイントを指し示す場合は、そのエンドポイントの MVC ビューまたは Razor ページを作成します。 UseStatusCodePagesWithReExecute の前に UseRouting が配置されていることを確認して、要求を状態ページに再ルーティングできるようにします。 Razor Pages の例については、 Pages/StatusCode.cshtml の を参照してください。
この方法は、アプリで次のことを行う必要がある場合によく使用されます。
別のエンドポイントにリダイレクトすることなく要求を処理する。 Web アプリの場合は、クライアントのブラウザーのアドレス バーに、初めに要求されていたエンドポイントが反映されます。
元の状態コードを保持し、応答で返す。
URL とクエリ文字列のテンプレートには、状態コード用のプレースホルダー ( {0} ) を含めることができます。 URL テンプレートの先頭には、スラッシュ ( / ) を付ける必要があります。 パスでプレースホルダーを使う場合は、エンドポイント (ページまたはコントローラー) でパスのセグメントを処理できることを確認します。 たとえば、エラー用の Razor ページでは、 @page ディレクティブの付いた省略可能なパスのセグメント値を受け入れる必要があります。
次の例で示すように、エラーを処理するエンドポイントでは、エラーを生成した元の URL を取得できます。
HttpGet などの HTTP メソッド属性を使ってエラー ハンドラー アクション メソッドをマークしないでください。 明示的な動詞を使用すると、要求がメソッドに届かないことがあります。 認証されていないユーザーにエラー ビューが表示される場合は、メソッドへの匿名アクセスを許可します。
状態コード ページを無効にする
MVC コントローラーまたはアクション メソッドの状態コード ページを無効にするには、 [SkipStatusCodePages] 属性を使用します。
Razor Pages ハンドラー メソッドまたは MVC コントローラーの特定の要求に対して状態コード ページを無効にするには、 IStatusCodePagesFeature を使用します。
例外処理ページのコードは例外をスローすることがあります。 実稼働のエラー ページは純粋に静的なコンテンツで構成することをお勧めします。
応答のヘッダーが送信された後は、次のようになります。
アプリで応答の状態コードを変更できません。
すべての例外ページやハンドラーを実行できません。 応答は完了している必要があります。あるいは、接続が中止となっている必要があります。
アプリ内の例外処理ロジックに加えて、 HTTP サーバーの実装 でも一部の例外を処理できます。 応答ヘッダーの送信前にサーバーで例外がキャッチされると、サーバーによって " 500 - 内部サーバー エラーです " 応答が応答本文なしで送信されます。 応答ヘッダーの送信後にサーバーで例外がキャッチされた場合、サーバーは接続を閉じます。 アプリで処理されない要求はサーバーで処理されます。 サーバーが要求を処理しているときに発生した例外は、すべてサーバーの例外処理によって処理されます。 この動作は、アプリのカスタム エラー ページ、例外処理ミドルウェア、およびフィルターから影響を受けません。
アプリの起動中に起こる例外はホスティング層だけが処理できます。 起動時のエラーをキャプチャ したり、 詳細なエラーをキャプチャ したりするように、ホストを構成することができます。
ホスティング レイヤーでは、ホスト アドレス/ポート バインド後にエラーが発生した場合にのみ、キャプチャされた起動時エラーに対するエラー ページを表示できます。 バインドが失敗した場合は、次のようになります。
ホスティング レイヤーにより重大な例外がログに記録されます。
dotnet プロセスがクラッシュします。
HTTP サーバーが Kestrel のときは、エラー ページは表示されません。
IIS (または Azure App Service) または IIS Express 上で実行している場合、プロセスを開始できなければ、 ASP.NET Core モジュール から " 502.5 - 処理エラー " が返されます。 詳細については、「 Azure App Service および IIS での ASP.NET Core のトラブルシューティング 」を参照してください。
データベース エラー ページ ミドルウェアは、Entity Framework の移行を使用して解決できるデータベース関連の例外をキャプチャします。 これらの例外が発生すると、問題が解決する可能性のあるアクションの詳細を含む HTML 応答が生成されます。 このページは、 Development 環境でのみ有効にする必要があります。 ページを有効にするには、コードを Startup.Configure に追加します。
UseDatabaseErrorPage には、 Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore NuGet パッケージが必要です。
MVC アプリでは、例外フィルターをグローバルに、またはコントローラーやアクションの単位で構成できます。 Razor Pages アプリでは、グローバルに、またはページ モデルの単位で構成できます。 このようなフィルターはコントローラー アクションや別のフィルターの実行中に発生する未処理の例外を処理します。 詳細については、「 ASP.NET Core フィルター 」を参照してください。
例外フィルターは、MVC アクション内で発生する例外をトラップするのに役立ちますが、例外処理ミドルウェアほど柔軟性がありません。 ミドルウェアの使用をお勧めします。 選択された MVC アクションに応じて異なる方法でエラー処理を実行する必要がある場合にのみ、フィルターを使用します。
モデル状態エラーを処理する方法については、 モデル バインド および モデルの検証 に関する記事をご覧ください。
Azure App Service および IIS での ASP.NET Core のトラブルシューティング
ASP.NET Core を使用した Azure App Service および IIS の一般的なエラーのトラブルシューティング
このページはお役に立ちましたか?
このトピックについてサポートが必要ですか?
このトピックの意図を把握したり、理解を深めたりするために Ask Learn を使ってみませんか?
Last updated on 2026-08-10