2008年7月29日火曜日

IsMvcAjaxRequest

ナオキさんのサイトで取り上げられていたので、流行りに乗っかっていこうと思います! ASP.NET MVC Preview 4からAjaxが少しとりいれられてます。

クライアントサイドはMicrosoft Ajax Libraryがベース。 これの使いどころはやっぱり部分更新ですよね。ASP.NET AJAXならUpdatePanelのような動きと言えばわかりやすいかな?

とにかく動かしてみることにしましょう。 まずは、Preview 4のプロジェクトテンプレートで新しいプロジェクトを作成。 そしたら、AccountControllerとHomeContoroller、Views/AccoutとViews/Homeとか出てきます。 Views/Homeの中には最初に表示されるIndex.aspxとAboutページのAbout.aspxが出来てます。 とりあえずHomeControllerのIndexアクションとViews/Home/Index.aspxだけを使って試してみることにします。

初期のIndexアクションは↓。

public ActionResult Index()
{
ViewData["Title"] = "Home Page";
ViewData["Message"] = "Welcome to ASP.NET MVC!";

return View();
}

Index.aspxは↓。

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
   <h2><%= Html.Encode(ViewData["Message"]) %></h2>
   <p>
       To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
   </p>
</asp:Content>

なんとまぁ、スッキリしたものが出てきますわ。 ※ViewData["Title"]はShared/Site.Masterで使ってますよ。 で、ページにFORMを張り付けてPOSTさせてみよう! IndexアクションでPOSTした値を取得してViewDataに入れようじゃないですか。

public ActionResult Index()
{
 ViewData["Title"] = "Home Page";
 ViewData["Message"] = "Welcome to ASP.NET MVC!";
   
 ViewData["result"] = "";
 if (Request.HttpMethod.ToLower() == "post")
 {
   ViewData["result"] = string.Format("こんにちは、{0} さん!", Request.Form["yourName"]);
 }

 return View();
} 

↓これをIndex.aspxに追加(</p>の後に)。

    <% using (Html.Form("Home", "Index"))
      { %>

      名前は?<%= Html.TextBox("yourName") %>
      <input type="submit" value="ぼたん" />
      <span id="result"><%= ViewData["result"] %></span>
    
   <%} %>

こんな感じですね。POSTしたyourNameをViewData["result"]入れて、それをspanタグ内に表示するものです。ここまではすんなりです。 img.aspx

↑こんな表示になるんで、テキストボックスに適当になんか入れて「ぼたん」押すと、↓こんな感じでボタンの横に表示されます。

img.aspx2 とびっきり普通の処理です。

ここからです! IndexアクションへのPOSTが発生した場合、ブラウザからのものなのかXMLHttpRequestからのものなのかを簡単に判別する方法として、Request.IsMvcAjaxRequest()というのがあるので、それを使うことにします。 なので、Indexアクションを変更。

    public ActionResult Index()
   {
     ViewData["Title"] = "Home Page";
     ViewData["Message"] = "Welcome to ASP.NET MVC!";
   
     ViewData["result"] = "";
     if (Request.HttpMethod.ToLower() == "post")
     {
       ViewData["result"] = string.Format("こんにちは、{0} さん!", Request.Form["yourName"]);
        if (Request.IsMvcAjaxRequest())
         return Content((string)ViewData["result"]);
      }

     return View();
   } 

↑太字の部分が追加したコードです。 差を分かりやすくするのに、Index.aspxには追加でAjax.Formを入れることにします。 なので、Index.aspxの全体は↓。

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication5.Views.Home.Index" %>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
   <script src="/Content/MicrosoftAjax.debug.js" type="text/javascript"></script>
   <script src="/Content/MicrosoftMvcAjax.debug.js" type="text/javascript"></script>
 
   <h2><%= Html.Encode(ViewData["Message"]) %></h2>
   <p>
       To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
   </p>
 
   <% using (Html.Form("Home", "Index"))
      { %>

      名前は?<%= Html.TextBox("yourName") %>
      <input type="submit" value="ぼたん" />
      <span id="result"><%= ViewData["result"] %></span>
    
   <%} %>
 
   <% using (Ajax.Form("Index", new AjaxOptions { UpdateTargetId = "result2" }))
      { %>
    
      名前は?<%= Html.TextBox("yourName") %>
      <input type="submit" value="ぼたん" />
      <span id="result2"><%= ViewData["result"] %></span>
    
   <% } %>
 
</asp:Content>

これを実行すると2つのテキストボックスとボタンが表示されます。 img.aspx3

フォームも2つあるからそりゃそうですね。 最初に上段のテキストボックスとボタンに”さる”と入れて上段のボタンを押します。

img.aspx4

ボタンの横に両方とも”さる”と出ます。 続いて、下段のテキストボックスに”いぬ”と入れて下段のボタンを押します。

img.aspx5 小さすぎて見にくい...。 まぁ、それはいいとして、下段だけが"いぬ"になりましたね。 結果だけを見ると分かりにくいんですけど、実際にコードを書くとですよ、上段のボタンはページ全体をPOSTで取得するのに対し、下段はボタン横のテキストのみAJAXで取得して書き換えてる動きになってるのが確認できると思います。