新しもの好きプログラマの耳より情報ブログ

仕事でもあるプログラミングについて役に立ちそうな情報を発信していこうというブログです。役に立たなそうな情報はfacebookで。

ASP.NET MVCのRazorでMicrosoft AJAXを使うには依存スクリプトの明示的な読み込みが必要

ASP.NET MVCのRazorでMicrosoft AJAXを使ってみようとして、「部分更新が動かないが、特にエラーも出ない」という困った状況になってしばらくググる羽目になったので、動かすまでに必要なことの情報をまとめておく。使用環境はVisual Studio 2013 Update3。

これが旧方式のASPXだったらかなり情報はあるし、定番のASPX用ライブラリを使うタグをひとつ入れれば良いだけなので多分すぐ解決したのだと思う。しかし新しいRazorはそれ自体が便利な代わりに過去の便利ライブラリが使えない事が多いようだ。これは新しい言語やフレームワークの宿命かもしれない。

 

では起きた問題とその解決方法の話に入る。

 

条件を指定して検索ボタンを押すと、その結果だけを部分更新するページを作ってみようと考えた。

JQueryで組んでも良いが、せっかくASP.NETを使っているのでMicrosoftAJAXで楽をしようと次のようなコードを書いた。

@model ASPTry1.Models.User

@{ var ajaxOptions = new AjaxOptions

           {

               UpdateTargetId = "ResultList",

               HttpMethod = "GET",

               LoadingElementId = "LoadingElement",

           }; }

@using (Ajax.BeginForm("UserQuery", "Users", ajaxOptions))

{

<fieldset>

   <legend>ユーザー検索</legend>

   <p>

       @Html.LabelFor(item => item.Name) : @Html.TextBoxFor(item => item.Name, new { size = 30 })

   </p>

   <p>

       <input id="Submit" type="submit" value="検索" />

   </p>

</fieldset>

}

<div id="LoadingElement" hidden="hidden">

   Loading...

</div>

<div id="ResultList"></div>

 

実行すると問題なくページが表示されたが、検索ボタンを押すとページ全体が変更されてしまって部分更新にならない。

 

サーバー側のコードをデバッグしてみたところ、アクションは呼ばれているがRequest.IsAjaxRequestがfalseを返している。つまりAjaxが動作していない。

 

結論としては、依存スクリプト不足だった。

調べてみたところ、まずそもそもMicrosoft AJAXスクリプトを読まないといけない。

さらにその内部でjQueryの機能を使うのでそれらのスクリプトも必要なようだ。

WindowsAPIなどは必要な依存ファイルがMSDNに全て書かれているが、Webアプリはそうは行かないらしい。

 

次のスクリプトを事前に読み込むことで、部分更新が正常に動作するようになった。

   <script src="~/Scripts/jquery-1.10.2.min.js" type="text/javascript"></script>

   <script src="~/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>

   <script src="~/Scripts/MicrosoftAjax.js" type="text/javascript"></script>

   <script src="~/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>

jquery-1.10.2.min.jsは初期状態でBundleConfigに含まれているため実は不要

 

また、そのスクリプトは初期状態ではプロジェクトに含まれていないので次のNuGetパッケージを追加した。

MicrosoftAjax

MicrosoftMvcAjax.Mvc5

Microsoft jQuery Unobtrusive Ajax

※「jQuery Unobtrusive Ajax」という類似品があるが、これは「Legacy package」と明記してあるので注意

 

解決してみると大したことはやっていないが、これらが必要だという情報が意外とまとまっていないので苦労する。同じ問題で引っかかっている人の役に立てば嬉しい。

 

ところで結論としては依存スクリプト不足だったのだが、ここはWebアプリの難しいところのようだ。デスクトップアプリならば依存不足があれば例外を出してクラッシュするし、そもそもヘッダを組み込んでいなければコンパイルエラーになるので問題を見つけやすい。しかしWebアプリではスクリプトがなくてもIntelliSenseは情報を出すし、実行しても何のエラーも出ず処理を続行してしまう。デバッグに慣れが必要だ。