normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

ASP.NET MVC3 RC2のJsonValueProviderFactoryを利用して非同期処理を試す!

以前、ASP.NET MVC3から導入されたJsonValueProviderFactoryの利用方法を紹介した id:waritohutsu:20100926:1285487020 。しかし、同記事で利用したASP.NET MVC3はPreview版であり、最新のRC2とは取り扱い方法が異なる*1。今回はASP.NET MVC3 RC2でJsonValueProviderFactoryを利用する方法を紹介する。

概略

今回は以下のアプリケーションを利用してJsonValueProviderFactoryについて紹介する。

画面側からGETリクエスト/POSTリクエストを非同期に飛ばし、Controller側では受け取ったリクエストデータの内容を標準出力に表示するだけの簡単なアプリケーションだ。SkyDrive上にMvc3RC2App.zipを公開したので、是非実際に動作させて頂きたい。
GETリクエストについては、初回以外はブラウザキャッシュが利用されているのかリクエストが飛ばなかった。何気なくだが、「GETリクエストは参照用」で「POSTリクエストは更新用」での利用がオススメの予感だ。

ソースコード解説

  • Views/Home/Index.cshtml

GETリクエストとPOSTリクエストでデータを飛ばす方法について記述している。GETリクエストとPOSTリクエストでは、データを送付する方法が異なる*2ことに注意して頂きたい。

@{
    ViewBag.Title = "Home Page";
}
<script type="text/javascript">
    function SendJsonGet() {
        //クエリストリングを作成
        var queryString = "Name=" + encodeURIComponent("高町 美由希")
            + "&Comment=" + encodeURIComponent("御神真刀流小太刀二刀術");

        //以下の場合、日本語が文字化けした(涙
        //decodeURIComponent($.param({"Age":17, "Name": "高町 美由希"}));

        $.ajax({
            type: "GET",
            dataType: "json",
            contentType: 'application/json',
            url: 'Home/JsonGetMethod?' + queryString,
            success: function (serverResponse) {
                //サーバサイドから受け取ったJSon形式レスポンスデータを表示する
                $('#message').html(JSON.stringify(serverResponse));
            },
            error: function () {
                alert('エラー終了です');
            }
        });
    }

    function SendJsonPost() {
        var data = {
            "Age": 9,
            "Name": "高町 なのは",
            "Comment": "リリカルマジカル"
        };

        //JSON形式のシリアライズ処理
        var jsonString = JSON.stringify(data);

        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: 'application/json',
            url: 'Home/JsonPostMethod',
            data: jsonString,
            success: function (serverResponse) {
                //サーバサイドから受け取ったJSon形式レスポンスデータを表示する
                $('#message').html(JSON.stringify(serverResponse));
            },
            error: function () {
                alert('エラー終了です');
            }
        });
    }
</script>

@using (Html.BeginForm())
{
    <h2>@ViewBag.Message</h2>

    <input type="button" name="get_button" value="GETリクエスト" onclick="javascript:SendJsonGet()" /> <br />
    <input type="button" name="post_button" value="POSTリクエスト" onclick="javascript:SendJsonPost()" /> <br /> <br /> <br />
    
    <div id="message" style="border-style: dotted; font-size: x-large; color: #FF0000;">
        結果表示領域
    </div>
}

また、上記のJavaScriptソース内で利用している「JSON.stringify」メソッドはモダンブラウザでのみ実装されており、IE6等の古いブラウザでは実装されていない。詳細は「Testing native JSON」と「MSDN Blogs > IEBlog > Native JSON in IE8」を参照して頂きたい。

  • Controllers/HomeController.cs

GETリクエスト側では、HomeController.Jsonメソッドの第二引数に「JsonRequestBehavior.AllowGet」を設定している点に注意して頂きたい。

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            return View();
        }

        public ActionResult About()
        {
            return View();
        }

        [HttpPost]
        public ActionResult JsonPostMethod(Person person)
        {
            //POSTリクエストのデータ表示
            System.Diagnostics.Trace.TraceInformation(
                "☆☆ person.Name={0}, person.Age={1}, person.Commnet={2}"
                , person.Name, person.Age, person.Comment);

            return Json(new Person()
            {
                Age = 14,
                Name = "白鳥星座の氷河",
                Comment = "ダイヤモンドダスト!"
            });
        }

        [HttpGet]
        public ActionResult JsonGetMethod(Person person)
        {
            //GETリクエストのデータ表示
            System.Diagnostics.Trace.TraceInformation(
                "★★ person.Name={0}, person.Age={1}, person.Commnet={2}"
                , person.Name, person.Age, person.Comment);

            //「JsonRequestBehavior.AllowGet」を設定しないと、GETリクエストを処理できない
            return Json(new Person()
            {
                Age = 13,
                Name = "天馬星座の星矢",
                Comment = "燃え上がれ俺の小宇宙!"
            }, JsonRequestBehavior.AllowGet);
        }
    }

    public class Person
    {
        public int Age { get; set; }
        public string Name { get; set; }
        public string Comment { get; set; }
    }

*1:ValueProviderFactories.Factoriesに対するJsonValueProviderFactoryの登録が不要になった

*2:POSTリクエストはBODY部、GETリクエストはクエリストリング