ASP.NET MVCを勉強中で、ちょっとしたサンプルを作っている。
その中で、JavaScriptを外部ファイルとして追加する時にファイルが見つからずに読み込めないという意外な現象ではまったので紹介する。
MSDNの解説などにある通りに「jsファイルは全部Scriptフォルダに入れる」とした場合はこの問題は起きない。
特定のページでしか使わないjsファイルなので、そのページが入っているViewのフォルダに一緒に入れよう、と考えたところこの問題が起きた。
この問題をさらりと解決してくれた素晴らしい記事があったが、一工夫加える必要があったのでその記事を引用しつつ解説する。
>お楽しみはこれからだ! ASP_NET MVCでJavaScriptを上手いこと使う
>http://takepara.blogspot.jp/2009/03/aspnet-mvcjavascript.html
この記事にある通り、Viewフォルダ下にあるファイルには普通にURLを指定してもアクセス出来ないようだ。
自力でカスタムのルーティング処理をしてやる必要がある。
記事の通りに実装してみたが、これだけでは動作しなかった。IISの設定にも絡むので環境の違いかもしれない。(VisualStudio2013+IIS Expressの環境でデバッグしている)
どうやら拡張子.jsが付いたURLがIISに処理されてしまってルーティングに引っかからないようだ。
この問題はweb.configに次の設定を加えて.jsファイルへのアクセスをASP.NETのルーティングに回させるようにする事で解決した。
<configuration>
<system.webServer>
<handlers>
<add name="JavaScriptFileRoutingHandler" path="*.js" verb="*" type="System.Web.Handlers.TransferRequestHandler"/>
</handlers>
</system.webServer>
</configuration>
※preCondition指定は必須ではなく意味を十分に理解していないが、自動生成の設定に合わせて入れた
代わりに.jsファイルへのアクセス失敗はASP.NETでエラーハンドリングしてやる必要が出てくるが、特に実害はないはず。まだサンプル作成段階なのでそこまでは考えない。
2014/8/24 追記
上記のようにすると、元々アクセス可能だったScriptフォルダにある.jsファイルが読めなくなってしまう事に気づいた。それもルーティングの対象になるためか。
次のように、View用に作った仮想フォルダのパスを条件にすればそのような問題は起きない。
<system.webServer>
<handlers>
<add name="JavaFileRoutingHandler" path="/ViewScripts/*" verb="*" preCondition="integratedMode" type="System.Web.Handlers.TransferRequestHandler" />
</handlers>
</system.webServer>
以上。組み込んだルーティング処理がなぜ呼ばれないのか切り分けるためにルーティングの資料を一から読み直すなど1日かかってしまった。
まだASP.NET MVC自体の理解が浅いな・・・。