2007/02/26

Dojo -- JSONPに挑む。 【白帯編】

取り敢えずAjaxなライブラリとして使い始めたDojoですが、使い方というか流儀みたいなのがそれなりに理解出来たような気がするので、次の一歩としてJSON、それもCross Domainな呼び出しをする為にJSONPをと思っています。

JSONPServiceも他所様のサービスではなく自前で提供をと考えていますので、Server側のArchitectureも合わせて考慮する必要があり、PHPというのがPrivateな利用面ではMajorityなんでしょうが、個人的な好みからASP.NETで挑みます。

Sever側からはベタな手法としてRespone.Write()で手作りとかってのもあるんですが、ここはオシャレなLibraryを使ってみたいと思い、今回はJayrockを使ってみました。


JayrockLGPLでライセンスされており、単純な入出力のFormatter/Parserという面の他に、HTTP Handlerを利用したJSON-RPC的な実装も可能なかなり強力なLibraryです。

今回は取り敢えずJSONPな出力をするaspxなページを取り敢えず作ってみました。Jayrockのサンプルから引用したコードを新規のaspx.csに貼り付けた感じですが、JSONPの動作/雰囲気を掴むにはこんなもので十分かと。

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using Jayrock.Json;
using Jayrock.Json.Conversion;

public partial class jsonpTest : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

        string callBackFunctionName = null;

        if (Request["callback"] != null)
        {
            callBackFunctionName = Request["callback"];
            Response.Write(callBackFunctionName + "(");
        }

        using (JsonWriter writer = CreateJsonWriter(Response.Output))
        {
            writer.WriteStartObject();              //  {
            writer.WriteMember("Name");             //      "Name" : 
            writer.WriteString("John Doe");         //          "John Doe",
            writer.WriteMember("PermissionToCall"); //      "PermissionToCall" :
            writer.WriteBoolean(true);              //          true,
            writer.WriteMember("PhoneNumbers");     //      "PhoneNumbers" :
            writer.WriteStartArray();               //          [ 
            WritePhoneNumber(writer,                //            { "Location": "Home",
                "Home""555-555-1234");            //              "Number": "555-555-1234" },
            WritePhoneNumber(writer,                //            { "Location": "Work",
                "Work""555-555-9999 Ext. 123");   //              "Number": "555-555-9999 Ext. 123" }
            writer.WriteEndArray();                 //          ]
            writer.WriteEndObject();                //  }
        }

        if (Request["callback"] != null)
            Response.Write(");");
    }

    private  void WritePhoneNumber(JsonWriter writer, string location, string number)
    {
        writer.WriteStartObject();      //  {
        writer.WriteMember("Location"); //      "Location" : 
        writer.WriteString(location);   //          "...", 
        writer.WriteMember("Number");   //      "Number" :
        writer.WriteString(number);     //          "..."
        writer.WriteEndObject();        //  }
    }

    private  JsonWriter CreateJsonWriter(TextWriter writer)
    {
        JsonTextWriter jsonWriter = new JsonTextWriter(writer);
        jsonWriter.PrettyPrint = true;
        return jsonWriter;
    }
}

ちなみにaspxファイルはこんな感じてデフォルトで作成された物から最初の一行以外は全部削ります。

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="jsonpTest.aspx.cs" Inherits="jsonpTest" %>

そしてクライアントになるhtmlファイルはこんな感じです。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
  <head>
    <script type="text/javascript" src="../dojo/dojo.js"></script>
    <script type="text/javascript">
        
        dojo.require("dojo.io");
        dojo.require("dojo.io.ScriptSrcIO");
        dojo.require("dojo.json");

        function testJSONP() {
        dojo.io.ScriptSrcTransport.bind({
          url: 'http://ilgvkteq.sv05.fsdotnet.net/ngm/jsonpTest.aspx'
          ,transport: "ScriptSrcTransport"
          ,jsonParamName: "callback"
          ,load: function(type, data, event, req) {
            showResult(data);
            }
        });
        }

        function showResult(result) {
            document.getElementById('output').innerHTML =dojo.json.serialize(result);
        }
    </script>
  </head>
  <body>

    <input type="button" onclick="testJSONP()" value="Test JSONP"/>
    <br /><br /><br />
    <div id="output"></div>

  </body>

</html>

このBloggerPost(記事)にはScriptを埋められないので、動作してる画面はこんな感じ。



ボタンを押すと、



かなり手抜きなテストですが、SeverからのResponseJavascriptObjectとして捕らえられている事とCallBackの指定の仕方が分かるので、白帯編としてはこれで十分かと。

この次は茶帯編として、JSONPで得た結果からGridの描画とかをと思っています。

関連のありそうな記事

0 コメント: