ASP.NET MVCのカスタムエラーページで、ドツボにハマったのでメモがてら記事におこしました。
カスタムエラーはIIS側に統一させる
試行錯誤の結果、しばやんさんが紹介して頂いている「IIS側に統一」する形が一番良いのだと実感しました。当初customErrorsだけを設定していて、MVC側のエラー捕捉は出来てもhtml側が捕捉できないぞ、と誰しもが一度は通る道を経験し、しばらくはcustomErrorsとhttpErrors の両方を Web.config に追加する形で実装していました。
でも面倒くさがりな自分は2箇所も修正するなんて面倒だ!ああ面倒だ、と思い調べなおすと、IIS側に統一という素敵な解に出会えたわけです。
落とし穴は仮想ディレクトリ時の「〜(チルダ)」
通常時は問題ないのですが、root以下に仮想ディレクトリを作成するアプリの場合などにハマりポイントが存在しました。
こんなパス→ https://mySIte/SubContents/・・・・・
customErrorsを書く際、こんな風に書きます。
<system.web> <customErrors mode="RemoteOnly"> <error statusCode="404" redirect="〜/Error/NotFound"/> </customErrors> </system.web>
ASP.NET MVCにおける「〜」はアプリケーションルートを表す記号で絶対パスを取得できます。ところが、この記述をIIS側の設定であるhttpErrorsに書くと・・・
<system.webServer> <httpErrors errorMode="Custom" existingResponse="Replace"> <remove statusCode="404" /> <-- ここのチルダがおかしい原因 --> <error statusCode="404" path="〜/Error/NotFound" responseMode="ExecuteURL" /> </httpErrors> </system.webServer>
HTMLステータスが502 Bad Gateway が返ってきたりします。
httpErrosではチルダによる変換はないっぽい
存在しない場所へパスを示しているのでエラーとなっていると気づいたのはしばらくしてからでした。
試しにpathの部分に仮想ディレクトリ名である「SubContents」を入れるとすんなり動いたという。。。
<system.webServer> <httpErrors errorMode="Custom" existingResponse="Replace"> <remove statusCode="404" /> <-- チルダの代わりに仮想ディレクトリ名を入れる --> <error statusCode="404" path="/SubContents/Error/NotFound" responseMode="ExecuteURL" /> </httpErrors> </system.webServer>
ああああ、でも釈然としない。気持ち悪い。コード内でconfig生成した方がスムーズになるかもしれない。要件が落ち着いたら試してみるか。。。