WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

jQuery Ajax で xml 形式のデータ受け取り

by WebSurfer 17. July 2012 21:37

jQuery Ajax で Web サービスを呼び出し、xml 形式のデータを受け取る場合の話です。

まず、Web サービスのメソッドの戻り値の型の形式として XML を指定するときは、ScriptMethodAttribute 属性 を追加し、ResponseFormat プロパティ を Xml に設定します。さらに、メソッドが XmlDocument オブジェクト を返すようにします。以下のような感じです。

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public XmlDocument GetXmlDocument()
{
    // Xml 形式の文字列を組み立て。
    string _xmlString = CreateXmlString();

    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(_xmlString);
    return xmlDoc;
}

こうしておくと、XmlDocument オブジェクトはサーバーで Xml 形式の文字列にシリアル化され、このメソッドを呼んだクライアントに返されます。また、応答ヘッダには Content-Type: text/xml が含まれるようになります。

ScriptMethod 属性の ResponseFormat プロパティを Xml に設定しておかない場合、Web サービスのメソッドが返すデータの形式は、クライアントからの要求ヘッダの Content-Type の指定によるようです。

クライアントからサーバーへデータを送信する場合、要求ヘッダの Content-Type は、application/x-www-form-urlencoded または application/json のいずれかになるはずです(データを送信しない場合、Content-Type を指定しないこともありますが)。

前者は普通に form データをサーバーに POST する時のデータ形式、後者は Ajax でのデータ交換フォーマットのデファクトスタンダード(?)である JSON 形式です。

要求ヘッダの Content-Type が application/json となっている場合、ScriptMethod 属性の ResponseFormat プロパティを Xml に設定しておかないと、戻り値が Xml 形式にならない(といって、正しい Json 形式にもならない)ので注意してください。

要求ヘッダの Content-Type を設定しない、または application/x-www-form-urlencoded とした場合は、ResponseFormat プロパティの設定に関係なく、戻り値は Xml 形式になります。(ResponseFormat プロパティを Json 設定しても無視されて、戻り値は Xml 形式になります。)

クライアントで Web サービスからのデータを受け取るのは jQuery Ajax の success ハンドラです。jQuery Ajax は、サーバーからの応答ヘッダに含まれる Contetnt-Type を見て success ハンドラに渡すデータの形式を決めます。

jQuery API の解説ページ jQuery.ajax() に次の説明があります。

"The text and xml types return the data with no processing. The data is simply passed on to the success handler, either through the responseText or responseXML property of the jqXHR object, respectively."

上のサンプルに書いたコードの場合、Web サービスからの応答ヘッダに Contente-Type: text/xml が含まれますので、success ハンドラに渡される data は jqXHR.responseXML から取得されます。

jqXHR.responseXML は何かというと、MSDN ライブラリの responseXML property に書いてあるように、XML DOM オブジェクト(ただのシリアル化された文字列ではなく)になります。

シリアル化された文字列を表示したい場合は、IE であれば xml プロパティが使えます。詳しくは、MSDN ライブラリの IXMLDOMDocument/DOMDocument Members を参照してください。

ただし、xml プロパティは IE 専用なので、Mozilla 系のブラウザの場合は以下のように XMLSerializer を使用できます。

function getXmlDocument() {
  $.post("163-ScriptMethodAttribute.asmx/GetXmlDocument",
    function (data, textStatus, jqXHR) {
      $('#output').empty();
      $('#output').text(data.xml || 
        (new XMLSerializer()).serializeToString(data));
    }
  );
}

または、jqXHR.responseText から取得することも可能です。

Tags: , ,

AJAX

jQuery.ajax で form データを送信

by WebSurfer 14. July 2012 16:43

jQuery.ajax で form データを送信する方法です。ちょっとハマったので忘れないように書いておきます。

Fiddler によるキャプチャ画面

例えば、"日本語" と "URL エンコードされるか?" という文字列を送信する場合は以下のようにします。

data: 'aaa=' + '<%=Server.UrlEncode("日本語")%>' + 
    '&bbb=' + '<%=Server.UrlEncode("URL エンコードされるか?")%>'

または、

data: { aaa: '日本語', bbb: 'URL エンコードされるか?' }

後者は、"日本語" および "URL エンコードされるか?" という文字列を自動的に UrlEncode して、前者と同様な form データを作って送信してくれるので、こちらの方がお勧めです。

上の画像は、以下の jQuery Ajax のコードでデータを送信した時、送信データを Fiddler でキャプチャしたものです。URL エンコードされているのが分かります。

$.post("152-jQueryAjaxXml.asmx/GetXml",
    { aaa: '日本語', bbb: 'URL エンコードされるか?' },
    function (data, textStatus, jqXHR) {
        $('#output').text(data.xml);
    }
);

Tags: ,

AJAX

ACT の AutoComplete

by WebSurfer 14. April 2012 15:48

AJAX Control Toolkit (ACT) の AutoComplete を使ってみました。

AJAX Control Toolkit の AutoComplete

実装は特に難しいことはなく、アットマーク・アイティの AutoComplete コントロールで Google サジェスト風なオートコンプリート機能を実装するには? を参考にすれば機能的には問題なく動くと思います���

ただし、スタイルを何も設定しないと、TextBox と候補リスト(AutoCompleteExtender が生成する ul, li 要素を使ったリスト)の間にスペースができてしまいます。理由は、ul 要素の Margin のトップが何故か 40px になっているからです。(IE9 の開発者ツールで「レイアウト」を見ると分かります)

スペースのできるのが気に入らない場合は、CompletionListCssClass プロパティに自分でスタイルを定義する必要があります。以下に、その例を書いておきます。

Web Form(.aspx)

CompletionListCssClass プロパティに設定するスタイルは、margin: 0px !important; とするだけではダメで、以下のように他の要素も定義しなおす必要があります。

下の例で、CompletionListItemCssClass と CompletionListHighlightedItemCssClass も設定してありますが、TextBox と候補リストの間のスペースの調整には必要ないです(オマケです)。

<%@ Page Language="C#" %>

<%@ Register Assembly="AjaxControlToolkit" 
    Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
    .autocomplete
    {
        margin: 0px !important;
        padding: 0px !important;
        text-align: left;
        color: WindowText;
        overflow: auto;
        border-color: ButtonShadow;
        border-width: 1px;
        border-style: solid;
        list-style-type: none;
        background-color: inherit;
        height: 200px; 
    }

    .autocomplete_item
    {
        color: WindowText;
        background-color: Window;
        padding: 1px;
    }

    .autocomplete_highlightedItem
    {
        color: Black;
        background-color: rgb(255, 255, 153);
        padding: 1px;
    }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <ajaxToolkit:ToolkitScriptManager 
        ID="ToolkitScriptManager1" 
        runat="server">
    </ajaxToolkit:ToolkitScriptManager>
    <asp:TextBox ID="TextBox1" 
        runat="server" Columns="50">
    </asp:TextBox>
    <ajaxToolkit:AutoCompleteExtender 
        ID="TextBox1_AutoCompleteExtender" 
        runat="server"
        MinimumPrefixLength="2" 
        ServicePath="~/142-ACTAutoComplete.asmx" 
        TargetControlID="TextBox1"
        ServiceMethod="GetList"
        CompletionSetCount="20"
        CompletionListCssClass="autocomplete"
        CompletionListItemCssClass="autocomplete_item" 
        CompletionListHighlightedItemCssClass=
            "autocomplete_highlightedItem">
    </ajaxToolkit:AutoCompleteExtender>
    </form>
</body>
</html>

Web サービス(.asmx)

Web サービスは、クライアントスクリプトから呼び出して、JSON 形式のデータを返すように、クラスに ScriptService 属性を追加するところがポイントです。

以下の例で、データベースは Microsoft が無償で提供している Northwind サンプルデータベースの Products テーブルを使用しています。

<%@ WebService Language="C#" Class="_142_ACTAutoComplete" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Collections.Generic;
using System.Web.Configuration;
using System.Data;
using System.Data.SqlClient;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class _142_ACTAutoComplete  : WebService 
{
  [WebMethod]
  public string[] GetList(string prefixText, int count)
  {
    List<string> list = new List<string>();
    string connString = 
      WebConfigurationManager.
        ConnectionStrings["Northwind"].ConnectionString;
    string query = 
      String.Format(
        "SELECT TOP {0} ProductName FROM Products " + 
        "WHERE ProductName LIKE @ProductName", count);
    SqlConnection connection = new SqlConnection(connString);
    SqlCommand command = new SqlCommand(query, connection);
    SqlParameter param = 
      new SqlParameter("@ProductName", SqlDbType.NVarChar, 40);
    param.Value = "%" + prefixText + "%";
    command.Parameters.Add(param);

    try
    {
      connection.Open();
      SqlDataReader reader = command.ExecuteReader();

      while (reader.Read())
      {
        list.Add(reader.GetString(0));
      }
    }
    finally
    {
      connection.Close();
    } 

    return list.ToArray();
  }    
}

Tags: , ,

AJAX

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  June 2021  >>
MoTuWeThFrSaSu
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar