しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET の HTTP エラー画面の表示処理を IIS 側に統一する

以前に ASP.NET の customErrors と IIS の httpErrors の違いについて書きました。

結局、この時には customErrors と httpErrors の両方を Web.config に追加するという結論に達しましたが、やはり二つを同時に設定するのは手間なので IIS 側に統一してみました。

元々の Web.config はこのように記述していました。これをベースに変更します。

<system.web>
  <customErrors mode="On">
    <error statusCode="404" redirect="/home/error"/>
  </customErrors>
</system.web>
<system.webServer>
  <httpErrors errorMode="Custom">
    <remove statusCode="404" />
    <error statusCode="404" path="/home/error" responseMode="Redirect" />
  </httpErrors>
</system.webServer>

今回は customErrors での処理を行いたくないので、出来るだけ使わないように設定します。

<system.web>
  <customErrors mode="RemoteOnly" />
</system.web>

mode は適当な感じですが、開発中はエラーが見えた方が良いので RemoteOnly にします。ステータスコードによってエラーページのリダイレクトを行う設定は、要素ごと削除しました。

このままだと ASP.NET 側でエラーが発生した場合には IIS の設定がスキップされて、いつものカスタムエラーページが表示されてしまいますが、httpErrors の existingResponse を Replace に設定すると、関係なく IIS の設定に従って画面を表示することが出来ます。

<system.webServer>
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" />
    <error statusCode="404" path="/home/error" responseMode="ExecuteURL" />
  </httpErrors>
</system.webServer>

responseMode は ExecuteURL に設定してあります。この場合にはサーバー側で path に指定した URL を実行してくれるので、リダイレクトすることなくエラー画面を返すことが出来るようになります。

設定の詳細については IIS 公式サイトのリファレンスを参照しておいてください。

Adding HTTP Errors <error> | Microsoft Learn

これでカスタムなエラーページを URL そのままで表示できるようになりました。ASP.NET と IIS で発生した 404 エラーは両方この設定通りに処理が行われます。

しかし、このままだと 200 が返ってしまうので、ステータスコードを 404 に変更してビューを返します。

public class HomeController : Controller
{
    public ActionResult Error()
    {
        Response.StatusCode = 404;

        return View();
    }
}

余談になりますが、responseMode が Redirect を設定している場合には、TrySkipIisCustomErrors を true に設定しないと無限ループになります。

全て設定が終わったので、実際に開発者ツールを使って確認してみました。

URL はアクセスしたそのままで、カスタムエラー画面と 404 が返っていることが確認出来ました。