以前に 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 が返っていることが確認出来ました。