QA@IT
«回答へ戻る

回答を投稿

コメントに「Example 2 に書いてある形式で渡せば、そのあとは表示まで全部 Grid が面倒見てくれるはず」と書いておきながら、もしできなかったら何ですので、バージョン 1.4.3 の .js と .css をダウンロードして検証してみました。

Example 2 に書いてあることは間違いないようで(間違っているところもありますが、今回の検証には関係ないのでその話は割愛)、期待した結果が得られます。

せっかく作ったので検証に使ったコードをご参考にアップしておきます。

Microsoft が提供している SQL Server サンプルデータベース Northwind の Orders テーブル(14 フィールド x 830 レコード)を使用しています。

データを取得し、JSON 文字列にして渡すのは HTTP ハンドラを使用しました。コードは以下の通りです(Web サイトプロジェクトのものです)。

<%@ WebHandler Language="C#" Class="_0139_w2uiOrdersHandler" %>

using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.Serialization;
using System.Web.Configuration;
using System.Collections.Generic;
using System.Runtime.Serialization.Json;

public class _0139_w2uiOrdersHandler : IHttpHandler 
{    
  public void ProcessRequest (HttpContext context) 
  {
    GridData data = new GridData();
    data.records = new List<Record>();

    string connString = 
        WebConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
    string query = "SELECT * FROM [Orders]";
    using(SqlConnection conn = new SqlConnection(connString))
    {
      conn.Open();
      using (SqlCommand cmd = new SqlCommand(query, conn))
      {
        using (SqlDataReader reader = cmd.ExecuteReader())
        {
          if (reader != null)
          {
            while (reader.Read())
            {
              Record record = new Record();
              record.OrderID = reader.GetInt32(0);
              record.CustomerID = reader.IsDBNull(1) ? null : reader.GetString(1);
              record.EmployeeID = reader.IsDBNull(2) ? null : (int?)reader.GetInt32(2);
              record.OrderDate = reader.IsDBNull(3) ? null : (DateTime?)reader.GetDateTime(3);
              record.RequiredDate = reader.IsDBNull(4) ? null : (DateTime?)reader.GetDateTime(4);
              record.ShippedDate = reader.IsDBNull(5) ? null : (DateTime?)reader.GetDateTime(5);
              record.ShipVia = reader.IsDBNull(6) ? null : (int?)reader.GetInt32(6);
              record.Freight = reader.IsDBNull(7) ? null : (decimal?)reader.GetDecimal(7);
              record.ShipName = reader.IsDBNull(8) ? null : reader.GetString(8);
              record.ShipAddress = reader.IsDBNull(9) ? null : reader.GetString(9);
              record.ShipCity = reader.IsDBNull(10) ? null : reader.GetString(10);
              record.ShipRegion = reader.IsDBNull(11) ? null : reader.GetString(11);
              record.ShipPostalCode = reader.IsDBNull(12) ? null : reader.GetString(12);
              record.ShipCountry = reader.IsDBNull(13) ? null : reader.GetString(13);
              data.records.Add(record);
             }
           }
         }
       }
    }

    // キャッシュは無効にする
    context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    context.Response.Cache.SetExpires(DateTime.Now.ToUniversalTime());
    context.Response.Cache.SetMaxAge(new TimeSpan(0, 0, 0, 0));

    context.Response.ContentType = "application/json; charset=utf-8";

    data.status = "success";
    data.total = data.records.Count;

    // 参考記事「方法 : JSON データをシリアル化および逆シリアル化する」
    // https://msdn.microsoft.com/ja-jp/library/bb412179(v=vs.110).aspx        
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(GridData));
    ser.WriteObject(context.Response.OutputStream, data);

    // DateTime 型は \/Date(836406000000+0900)\/ のようにシリアライズされる。
  }

  public bool IsReusable 
  {
    get 
    {
      return false;
    }
  }

}

[DataContract]
internal class GridData
{
    [DataMember]
    internal string status { get; set; }

    [DataMember]
    internal int total { get; set; }

    [DataMember]
    internal List<Record> records { get; set; } 

}

[DataContract]
internal class Record
{
    [DataMember]
    internal int OrderID { get; set; }

    [DataMember]
    internal string CustomerID { get; set; }

    [DataMember]
    internal int? EmployeeID { get; set; }

    [DataMember]
    internal DateTime? OrderDate { get; set; }

    [DataMember]
    internal DateTime? RequiredDate { get; set; }

    [DataMember]
    internal DateTime? ShippedDate { get; set; }

    [DataMember]
    internal int? ShipVia { get; set; }

    [DataMember]
    internal decimal? Freight { get; set; }

    [DataMember]
    internal string ShipName { get; set; }

    [DataMember]
    internal string ShipAddress { get; set; }

    [DataMember]
    internal string ShipCity { get; set; }

    [DataMember]
    internal string ShipRegion { get; set; }

    [DataMember]
    internal string ShipPostalCode { get; set; }

    [DataMember]
    internal string ShipCountry { get; set; }    
}

それを以下のように url に設定すれば(以下のコードで 0139-w2uiOrdersHandler.ashx が上記の HTTP ハンドラ)、自動的に HTTP ハンドラに非同期呼び出しがかかって JSON 文字列が取得され、Grid にデータが表示されます。

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

<!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 id="Head1" runat="server">
    <title></title>
    <script src="/Scripts/jquery-1.8.3.js" type="text/javascript"></script>
    <script src="/Scripts/w2ui-1.4.3.js" type="text/javascript"></script>
    <link href="/Styles/w2ui-1.4.3.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript">
    //<![CDATA[
        $(function () {
            $('#myGrid').w2grid({
                name: 'myGrid',
                url: '0139-w2uiOrdersHandler.ashx',
                columns: [
                    { field: 'OrderID', caption: 'Order ID', size: '7%' },
                    { field: 'CustomerID', caption: 'Customer ID', size: '7%' },
                    { field: 'EmployeeID', caption: 'Employee ID', size: '7%' },
                    { field: 'OrderDate', caption: 'Order Date', size: '7%' },
                    { field: 'RequiredDate', caption: 'Required Date', size: '7%' },
                    { field: 'ShippedDate', caption: 'Shipped Date', size: '7%' },
                    { field: 'ShipVia', caption: 'Ship Via', size: '7%' },
                    { field: 'Freight', caption: 'Freight', size: '7%' },
                    { field: 'ShipName', caption: 'Ship Name', size: '7%' },
                    { field: 'ShipAddress', caption: 'Address', size: '7%' },
                    { field: 'ShipCity', caption: 'City', size: '7%' },
                    { field: 'ShipRegion', caption: 'Region', size: '7%' },
                    { field: 'ShipPostalCode', caption: 'Postal Code', size: '7%' },
                    { field: 'ShipCountry', caption: 'Country', size: '7%' }
                ]                
            });
        });
    //]]>
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div id="myGrid" style="height: 450px"></div>
    </form>
</body>
</html>

スクロールは、Chrome 最新版なら何とか我慢できる程度に動きますが、IE9 あたりだと使い物にならないレベルの遅さでした。

コメントに「Example 2 に書いてある形式で渡せば、そのあとは表示まで全部 Grid が面倒見てくれるはず」と書いておきながら、もしできなかったら何ですので、バージョン 1.4.3 の .js と .css をダウンロードして検証してみました。

Example 2 に書いてあることは間違いないようで(間違っているところもありますが、今回の検証には関係ないのでその話は割愛)、期待した結果が得られます。

せっかく作ったので検証に使ったコードをご参考にアップしておきます。

Microsoft が提供している SQL Server サンプルデータベース Northwind の Orders テーブル(14 フィールド x 830 レコード)を使用しています。

データを取得し、JSON 文字列にして渡すのは HTTP ハンドラを使用しました。コードは以下の通りです(Web サイトプロジェクトのものです)。


```
<%@ WebHandler Language="C#" Class="_0139_w2uiOrdersHandler" %>

using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.Serialization;
using System.Web.Configuration;
using System.Collections.Generic;
using System.Runtime.Serialization.Json;

public class _0139_w2uiOrdersHandler : IHttpHandler 
{    
  public void ProcessRequest (HttpContext context) 
  {
    GridData data = new GridData();
    data.records = new List<Record>();
        
    string connString = 
        WebConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
    string query = "SELECT * FROM [Orders]";
    using(SqlConnection conn = new SqlConnection(connString))
    {
      conn.Open();
      using (SqlCommand cmd = new SqlCommand(query, conn))
      {
        using (SqlDataReader reader = cmd.ExecuteReader())
        {
          if (reader != null)
          {
            while (reader.Read())
            {
              Record record = new Record();
              record.OrderID = reader.GetInt32(0);
              record.CustomerID = reader.IsDBNull(1) ? null : reader.GetString(1);
              record.EmployeeID = reader.IsDBNull(2) ? null : (int?)reader.GetInt32(2);
              record.OrderDate = reader.IsDBNull(3) ? null : (DateTime?)reader.GetDateTime(3);
              record.RequiredDate = reader.IsDBNull(4) ? null : (DateTime?)reader.GetDateTime(4);
              record.ShippedDate = reader.IsDBNull(5) ? null : (DateTime?)reader.GetDateTime(5);
              record.ShipVia = reader.IsDBNull(6) ? null : (int?)reader.GetInt32(6);
              record.Freight = reader.IsDBNull(7) ? null : (decimal?)reader.GetDecimal(7);
              record.ShipName = reader.IsDBNull(8) ? null : reader.GetString(8);
              record.ShipAddress = reader.IsDBNull(9) ? null : reader.GetString(9);
              record.ShipCity = reader.IsDBNull(10) ? null : reader.GetString(10);
              record.ShipRegion = reader.IsDBNull(11) ? null : reader.GetString(11);
              record.ShipPostalCode = reader.IsDBNull(12) ? null : reader.GetString(12);
              record.ShipCountry = reader.IsDBNull(13) ? null : reader.GetString(13);
              data.records.Add(record);
             }
           }
         }
       }
    }
        
    // キャッシュは無効にする
    context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    context.Response.Cache.SetExpires(DateTime.Now.ToUniversalTime());
    context.Response.Cache.SetMaxAge(new TimeSpan(0, 0, 0, 0));
        
    context.Response.ContentType = "application/json; charset=utf-8";
        
    data.status = "success";
    data.total = data.records.Count;

    // 参考記事「方法 : JSON データをシリアル化および逆シリアル化する」
    // https://msdn.microsoft.com/ja-jp/library/bb412179(v=vs.110).aspx        
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(GridData));
    ser.WriteObject(context.Response.OutputStream, data);

    // DateTime 型は \/Date(836406000000+0900)\/ のようにシリアライズされる。
  }
 
  public bool IsReusable 
  {
    get 
    {
      return false;
    }
  }

}

[DataContract]
internal class GridData
{
    [DataMember]
    internal string status { get; set; }

    [DataMember]
    internal int total { get; set; }

    [DataMember]
    internal List<Record> records { get; set; } 

}

[DataContract]
internal class Record
{
    [DataMember]
    internal int OrderID { get; set; }
    
    [DataMember]
    internal string CustomerID { get; set; }
    
    [DataMember]
    internal int? EmployeeID { get; set; }
    
    [DataMember]
    internal DateTime? OrderDate { get; set; }
    
    [DataMember]
    internal DateTime? RequiredDate { get; set; }
    
    [DataMember]
    internal DateTime? ShippedDate { get; set; }
    
    [DataMember]
    internal int? ShipVia { get; set; }
    
    [DataMember]
    internal decimal? Freight { get; set; }
    
    [DataMember]
    internal string ShipName { get; set; }
    
    [DataMember]
    internal string ShipAddress { get; set; }
    
    [DataMember]
    internal string ShipCity { get; set; }
    
    [DataMember]
    internal string ShipRegion { get; set; }
    
    [DataMember]
    internal string ShipPostalCode { get; set; }
    
    [DataMember]
    internal string ShipCountry { get; set; }    
}
```

それを以下のように url に設定すれば(以下のコードで 0139-w2uiOrdersHandler.ashx が上記の HTTP ハンドラ)、自動的に HTTP ハンドラに非同期呼び出しがかかって JSON 文字列が取得され、Grid にデータが表示されます。

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

<!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 id="Head1" runat="server">
    <title></title>
    <script src="/Scripts/jquery-1.8.3.js" type="text/javascript"></script>
    <script src="/Scripts/w2ui-1.4.3.js" type="text/javascript"></script>
    <link href="/Styles/w2ui-1.4.3.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript">
    //<![CDATA[
        $(function () {
            $('#myGrid').w2grid({
                name: 'myGrid',
                url: '0139-w2uiOrdersHandler.ashx',
                columns: [
                    { field: 'OrderID', caption: 'Order ID', size: '7%' },
                    { field: 'CustomerID', caption: 'Customer ID', size: '7%' },
                    { field: 'EmployeeID', caption: 'Employee ID', size: '7%' },
                    { field: 'OrderDate', caption: 'Order Date', size: '7%' },
                    { field: 'RequiredDate', caption: 'Required Date', size: '7%' },
                    { field: 'ShippedDate', caption: 'Shipped Date', size: '7%' },
                    { field: 'ShipVia', caption: 'Ship Via', size: '7%' },
                    { field: 'Freight', caption: 'Freight', size: '7%' },
                    { field: 'ShipName', caption: 'Ship Name', size: '7%' },
                    { field: 'ShipAddress', caption: 'Address', size: '7%' },
                    { field: 'ShipCity', caption: 'City', size: '7%' },
                    { field: 'ShipRegion', caption: 'Region', size: '7%' },
                    { field: 'ShipPostalCode', caption: 'Postal Code', size: '7%' },
                    { field: 'ShipCountry', caption: 'Country', size: '7%' }
                ]                
            });
        });
    //]]>
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div id="myGrid" style="height: 450px"></div>
    </form>
</body>
</html>
```

スクロールは、Chrome 最新版なら何とか我慢できる程度に動きますが、IE9 あたりだと使い物にならないレベルの遅さでした。