KatsuYuzuのブログ

.NET の開発をメインとした日記です。

ASP.NET の customErrors、IISの httpErrors #aspnetjp

この記事はASP.NET Advent Calendar 2014 - Qiitaに参加しています。10日目の担当です。空いていたので登録しました。明日以降もまだ空いてますよ!
前日は@tanaka_733さんでした。

ASP.NET の customErrors、IISの httpErrors

ハマった & 毎回ぐぐるのでメモ。
ASP.NET と IIS のエラーについては@shibayanさんの記事を毎回ぐぐるので、先に紹介します。

9割は記事の紹介で済んでしまっているんですが、いろんな要素がミルフィーユのように重なっている部分なので、一つポカミスをやらかしていると途端に迷走します。軽くおさらいしながらポカミスの回避を紹介します。

ASP.NET

ASP.NET のエラーは customErrors でカスタマイズできます。

<system.web>
  <customErrors mode="RemoteOnly">
    <error statusCode="404" redirect="~/Error?source=MVC&amp;statusCode=404"/>
    <error statusCode="500" redirect="~/Error?source=MVC&amp;statusCode=500"/>
  </customErrors>
</system.web>

HandleErrorAttribute の確認

この時、グローバルフィルターで HandleErrorAttribute が設定されていないか確認してください。HandleErrorAttribute が設定されていると例外発生時にハンドルされ Error という View が返されてしまいます。

IIS

IIS のエラーは httpErrors でカスタマイズできます。

<system.webServer>
  <httpErrors errorMode="Custom">
    <remove statusCode="404"/>
    <remove statusCode="500"/>
    <error statusCode="404" path="https://localhost:xxxxx/Error?source=IIS&amp;statusCode=404" responseMode="Redirect"/>
    <error statusCode="500" path="https://localhost:xxxxx/Error?source=IIS&amp;statusCode=500" responseMode="Redirect"/>
  </httpErrors>
</system.webServer>

(2015/05/23 追記)上記サンプルにて"../Error……"としていましたが、この場合、パス階層を変えて404を出すと無限にパスを探しに行って最終的にIISの別の例外が飛んできます。設置環境に合わせてURLを指定するのが正解です。config切り替えなどで実現するといいですね。
パスの指定の仕方については次の「パスの確認」の項を確認してください。

パスの確認

この時、path と responseMode に注目してください。responseMode によって path に指定する値が相対パスなのか絶対パスなのか変わります。

デバッグでも本番環境に合わせて仮想ディレクトリを設定しておくとデプロイ後の不具合がないかと思います。

IIS のセットアップの確認

さらに、ローカルの IIS で確認している場合、最大の罠(ただのポカミス)がありました。IIS でカスタムエラーを表示するには [Windows の機能] から [インターネット インフォメーションサービス] > [World Wide Web サービス] > [HTTP 共通機能] > [HTTP エラー] を有効にする必要があります。
f:id:KatsuYuzu:20141210024229p:plain
これが有効になっていない場合、うんともすんとも言わずに IIS の標準のエラーが表示されます。私はこれが有効になっておらず、何か誤解しているのではないかと環境を疑わずにソース修正とデバッグをしていてかなりハマりました……。

デバッグ環境の構築

以前にこんなポカミス(SSL で挙動が変わる部分を非 SSL でデバッグしていた)もしていたわけですが、デバッグ環境は必ず本番環境に合わせてください。

IIS Express

IIS Express で SSL と仮想ディレクトリを使う方法を紹介しておきます。
まず、プロジェクトのプロパティウィンドウで [SSL 有効] を設定します。[SSL URL] をコピーしておいてください。
f:id:KatsuYuzu:20141210031027j:plain
次に、プロジェクトのプロパティ画面で先ほどコピーしておいた URL を張り付けて、ディレクトリの URL を追加しておきます。
f:id:KatsuYuzu:20141210031445j:plain
こうすることで、IIS Express でも SSL や仮想ディレクトリを使ったデバッグができるようになります。

Azure WebSites の利用

Azure が使える状況であれば利用しましょう。
[サーバー エクスプローラー] から WebSites を作成して、すぐに発行できます。
f:id:KatsuYuzu:20141210030947j:plain
f:id:KatsuYuzu:20141210030954j:plain
仮想ディレクトリの設定は、Visual Studio では行えないのでポータルへ移動してください。

ところで、Visual Studio の Azure WebSites の設定画面がちゃんと作られていてちょっと驚きました。
f:id:KatsuYuzu:20141210035239j:plain

サンプル

エラーを発生させるボタンを配置した、カスタムエラーを確認できるサンプルです。KatsuYuzu/aspnet-CustomErrorsSample · GitHub

バトンタッチ

11日目空いてますよ!