none
关于WebService返回DataTable RRS feed

  • 问题

  • 环境:VS2010、ASP.NET AJAX 4.0 客户端JS调用WebService返回的DataTable,百谷了半天,都是ASP.NET AJAX 2.0的情况,在web.config中加入DataConverter,需要引用Microsoft.Web.Preview.dll文件,据查是ASP.NET 2.0 AJAX Futures January CTP里的一个文件,可怎么没有4.0的呢?各位帮帮忙吧!
    2011年8月11日 3:20

答案

  • 也可以这样

    JavaScript 调用 ASP.NET WebService 的简单方法

    客户端 JavaScript 调用 ASP.NET WebService 的方法除了采用 WebServer.htc 和 构造 SOAPAction 的方法外,下面介绍一个采用 Ajax 调用的简单方法,并且可以传递参数。其实,ASP.NET WebService 就是一个网站,所以,Request 对象是可用的,这样,传递参数就很容易了。下面是一个WebService1.asmx的代码

    ASMX 代码
    <%@ WebService Language="C#" CodeBehind="WebService1.asmx.cs" Class="WebService1" %>

     

    C# 代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    using System.Data;

    /// <summary>
    /// Summary description for WebService1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo
    = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(
    false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    // [System.Web.Script.Services.ScriptService]
    public class WebService1 : System.Web.Services.WebService
    {
    [WebMethod]
    // 字符串返回测试
    public string GetServerTime()
    {
    return "当前服务器时间:" + DateTime.Now.ToString();
    }

    [WebMethod]
    // long 类型返回测试
    public long GetServerTimeTicks()
    {
    return DateTime.Now.Ticks;
    }

    [WebMethod]
    // Datatable返回测试
    public DataTable GetTestDataTable()
    {
    DataTable dt
    = new DataTable("TestTable");
    DataRow dr;
    dt.Columns.Add(
    new DataColumn("id", typeof(Int32)));
    dt.Columns.Add(
    new DataColumn("text", typeof(string)));
    for (int i = 0; i < 6; i++)
    {
    dr
    = dt.NewRow();
    dr[
    0] = i;
    dr[
    1] = "列表项目 " + i.ToString();
    dt.Rows.Add(dr);
    }
    return dt;
    }

    [WebMethod]
    // List 类型测试
    public List<User> GetTestUser()
    {
    //传递参数传测试
    string param = this.Context.Request.QueryString["param"];
    if (param == null) param= this.Context.Request.Form["param1"];
    List
    <User> u_list = new List<User>();
    for (int i = 0; i < 10; i++)
    {
    User u
    = new User();
    u.Name
    = "LoginName" + i.ToString() + " param = " + param;
    u.Title
    = "孟宪会" + i.ToString();
    u_list.Add(u);
    }
    return u_list;
    }

    //定义一个对象 User
    public class User
    {
    public String Name { get; set; }
    public String Title { get; set; }
    }
    }

    客户端调用的代码:

    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 runat="server">
    <title>JavaScript 调用 ASP.NET Web 服务测试</title>
    <script type="text/javascript">
    var xmlHttp = null;
    function createXMLHttpRequest() {
    try {
    if (window.XMLHttpRequest)
    xmlHttp
    = new XMLHttpRequest();
    else if (window.ActiveXObject)
    xmlHttp
    = new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (ex) { }
    }

    function AsynRequest() {
    createXMLHttpRequest();
    if (xmlHttp == null) {
    alert(
    "不能创建 XmlHttpRequest 对象");
    return;
    }
    xmlHttp.open(
    "GET", "WebService1.asmx/GetTestUser?param=net_lover", true);
    xmlHttp.setRequestHeader(
    "Connection", "close");
    xmlHttp.onreadystatechange
    = function () {
    if (xmlHttp.readyState == 4) {
    if (xmlHttp.status == 200) {
    var userList = xmlHttp.responseXML.getElementsByTagName("User");
    for (i = 0; i < userList.length; i++) {
    document.getElementById(
    "get1").innerHTML += userList[i].getElementsByTagName("Name")[0].firstChild.nodeValue + "";
    document.getElementById(
    "get1").innerHTML += userList[i].getElementsByTagName("Title")[0].firstChild.nodeValue + "<br/>";
    }
    }
    }
    };
    xmlHttp.send();
    }

    function AsynPostRequest() {
    createXMLHttpRequest();
    if (xmlHttp == null) {
    alert(
    "不能创建 XmlHttpRequest 对象");
    return;
    }
    var data = "param1=abc";
    xmlHttp.open(
    "POST", "WebService1.asmx/GetTestUser?t=" + Date.parse(new Date()), true);
    xmlHttp.setRequestHeader(
    "Content-type", "application/x-www-form-urlencoded");
    xmlHttp.setRequestHeader(
    "Content-length", data.length);
    xmlHttp.setRequestHeader(
    "Connection", "close");
    xmlHttp.onreadystatechange
    = function () {
    if (xmlHttp.readyState == 4) {
    if (xmlHttp.status == 200) {
    var userList = xmlHttp.responseXML.getElementsByTagName("User");
    for (i = 0; i < userList.length; i++) {
    document.getElementById(
    "post1").innerHTML += userList[i].getElementsByTagName("Name")[0].firstChild.nodeValue + "";
    document.getElementById(
    "post1").innerHTML += userList[i].getElementsByTagName("Title")[0].firstChild.nodeValue + "<br/>";
    }
    }
    }
    };
    xmlHttp.send(data);
    }
    </script>
    </head>
    <body>
    <input type="button" value="GET 方法调用" onclick="AsynRequest()" />
    <input type="button" value="POST方法调用" onclick="AsynPostRequest()" />
    <div id="get1"></div>
    <div id="post1"></div>
    </body>
    </html>

    需要注意的是:使用此方法需要在web.config里加入以下的配置:

    web.config 代码
    <system.web>
    <webServices>
    <protocols>
    <add name = "HttpPost" />
    <add name = "HttpGet" />
    </protocols>
    </webServices>
    </system.web>

    另外,也可以采用ASP.NET内置的方法进行调用,方法如下:

    ASPX 代码
    <%@ Page Language="C#" %>
    <script runat="server">
    public class User
    {
    public String UserName { set; get; }
    public Int32 Count { set; get; }
    public User() { }
    }
    [System.Web.Services.WebMethod]
    [System.Web.Script.Services.ScriptMethod]
    public static List
    <User> GetUsers(int count)
    {
    List
    <User> p = new List<User>();
    User x
    = new User();
    x.UserName
    = "AA";
    x.Count
    = 20;
    p.Add(x);

    x
    = new User();
    x.UserName
    = "AA";
    x.Count
    = count;
    p.Add(x);
    return p;
    }
    </script>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
    <script type="text/javascript">
    function GetData() {
    PageMethods.GetUsers((
    new Date()).getSeconds(), OnGetProductsComplete);
    }
    function OnGetProductsComplete(result) {
    for (i = 0; i < result.length; i++) {
    alert(result[i].UserName
    + " = " + result[i].Count);
    }
    }
    </script>
    </head>
    <body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" />
    <input id="Button1" type="button" value="测试" onclick="GetData()" />
    </form>
    </body>
    </html>
    这里需要配置
    Web.config 文件,可以启用 HTTP GET 和 HTTP POST。以下配置同时启用了 HTTP GET 和 HTTP POST:
    <configuration>
      <system.web>
      <webServices>
        <protocols>
          <add name="HttpGet"/>
          <add name="HttpPost"/>
        </protocols>
      </webServices>
      </system.web>
    </configuration>

    【孟子E章】
    2011年8月12日 4:44
    版主

全部回复

  • 无需设置啊,参见

    http://dotnet.aspx.cc/file/jQuery-Ajax-Call-WebService-DataTable.aspx


    【孟子E章】
    2011年8月12日 4:39
    版主
  • 另外,也可以这样

    jQuery 得到 ashx 返回的 JSON 格式的 DataSet 的方法


    对于代码中要注意的问题,已经添加了注释。

    ASPX 代码
    <%@ Page Language="C#" %>
    <!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>
    <title>dotnet.aspx.cc jQuery 测试</title>
    <script src="jquery-1.6.2.min.js" type="text/javascript"></script>
    <script type="text/javascript">
    function getData() {
    $(
    "#data").val("");
    jQuery.post(
    'GetList.ashx', {}, function (data) {
    var obj = JSON.parse(data);
    $.each(obj.Tables,
    function (index, table) {
    //根据不同的表名,显示不同的字段。得到特定表,table = obj.Tables[1]
    var tableName = table.Name;
    $.each(table.Rows,
    function (index, row) {
    if (tableName == "BlogArticle")
    $(
    "#data").val($("#data").val() + row.Title + "\r\n");
    else
    $(
    "#data").val($("#data").val() + row.UserName + "\r\n");
    });
    });
    })
    }
    </script>
    </head>
    <body>
    <form id="form1" runat="server">
    <textarea id="data" style="width: 200px; height: 500px"></textarea>
    <input type="button" value="得到数据" onclick="getData()" />
    </form>
    </body>
    </html>
    ASHX 代码
    <%@ WebHandler Language="C#" Class="GetList" %>

    using System;
    using System.Web;
    using System.Text;
    using System.Collections.Generic;
    using System.Collections;
    using System.Web.Script.Serialization;

    public class GetList : IHttpHandler
    {

    public void ProcessRequest(HttpContext context)
    {
    context.Response.ContentType = "text/plain";
    context.Response.Write(this.GetDataSet());
    }

    public bool IsReusable
    {
    get
    {
    return false;
    }
    }
    private String GetDataSet()
    {
    //测试用数据
    System.Data.DataSet ds = new System.Data.DataSet();
    System.Data.DataTable dataTable1 = new System.Data.DataTable("BlogUser");
    System.Data.DataRow dr;
    dataTable1.Columns.Add(new System.Data.DataColumn("UserId", typeof(System.Int32)));
    dataTable1.Columns.Add(new System.Data.DataColumn("UserName", typeof(System.String)));
    dataTable1.PrimaryKey = new System.Data.DataColumn[] { dataTable1.Columns["UserId"] };

    for (int i = 0; i
    < 8; i++)
    {
    dr
    = dataTable1.NewRow();
    dr[0] = i;
    dr[1] = "\"[<>{}],【孟子E章】" + i.ToString(); //特殊字符的测试
    dataTable1.Rows.Add(dr);
    }
    System.Data.DataTable dataTable2 = new System.Data.DataTable("BlogArticle");
    dataTable2.Columns.Add(new System.Data.DataColumn("ArticleId", typeof(System.Int32)));
    dataTable2.Columns.Add(new System.Data.DataColumn("Title", typeof(System.String)));
    dataTable2.Columns.Add(new System.Data.DataColumn("UserId", typeof(System.Int32)));
    dataTable2.PrimaryKey = new System.Data.DataColumn[] { dataTable1.Columns["ArticleId"] };
    Random rd = new Random();
    for (int i = 0; i
    < 20; i++)
    {
    dr
    = dataTable2.NewRow();
    dr[0] = i;
    dr[1] = "文章标题" + i.ToString();
    dr[2]
    = rd.Next(0, 7);
    dataTable2.Rows.Add(dr);
    }
    ds.Tables.Add(dataTable1);
    ds.Tables.Add(dataTable2);
    return Dataset2Json(ds);

    }

    /// <summary
    >
    /// dataTable转换成Json格式
    ///
    </summary>
    ///
    <param name="dt"></param>
    ///
    <returns></returns>
    public static string DataTable2Json(System.Data.DataTable dt)
    {
    StringBuilder jsonBuilder = new StringBuilder();
    jsonBuilder.Append("{\"Name\":\"" + dt.TableName + "\",\"Rows");
    jsonBuilder.Append("\":[");
    for (int i = 0; i
    < dt.Rows.Count; i++)
    {
    jsonBuilder.Append("{");
    for (int j
    = 0; j < dt.Columns.Count; j++)
    {
    jsonBuilder.Append("\"");
    jsonBuilder.Append(dt.Columns[j].ColumnName);
    jsonBuilder.Append("\":\"");
    jsonBuilder.Append(dt.Rows[i][j].ToString().Replace("\"","\\\"")); //对于特殊字符,还应该进行特别的处理。
    jsonBuilder.Append("\",");
    }
    jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
    jsonBuilder.Append("},");
    }
    jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
    jsonBuilder.Append("]");
    jsonBuilder.Append("}");
    return jsonBuilder.ToString();
    }

    /// <summary
    >
    /// DataSet转换成Json格式
    ///
    </summary>
    ///
    <param name="ds">DataSet</param>
    ///
    <returns></returns>
    public static string Dataset2Json(System.Data.DataSet ds)
    {
    StringBuilder json = new StringBuilder();
    json.Append("{\"Tables\":");
    json.Append("[");
    foreach (System.Data.DataTable dt in ds.Tables)
    {
    json.Append(DataTable2Json(dt));
    json.Append(",");
    }
    json.Remove(json.Length - 1, 1);
    json.Append("]");
    json.Append("}");
    return json.ToString();
    }
    }

    网上有DataSet转JSON格式的方法,是错误的,比如下面的这个,返回的格式搜有问题的,表的数据直接没有任何分割,所以不能使用 JavaScript 正确地解析。

    C# 代码
    #region dataTable转换成Json格式
    /// <summary>
    /// dataTable转换成Json格式
    /// </summary>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static string DataTable2Json(DataTable dt)
    {
    StringBuilder jsonBuilder
    = new StringBuilder();
    jsonBuilder.Append(
    "{\"");
    jsonBuilder.Append(dt.TableName.ToString());
    jsonBuilder.Append(
    "\":[");
    for (int i = 0; i < dt.Rows.Count; i++)
    {
    jsonBuilder.Append(
    "{");
    for (int j = 0; j < dt.Columns.Count; j++)
    {
    jsonBuilder.Append(
    "\"");
    jsonBuilder.Append(dt.Columns[j].ColumnName);
    jsonBuilder.Append(
    "\":\"");
    jsonBuilder.Append(dt.Rows[i][j].ToString());
    jsonBuilder.Append(
    "\",");
    }
    jsonBuilder.Remove(jsonBuilder.Length
    - 1, 1);
    jsonBuilder.Append(
    "},");
    }
    jsonBuilder.Remove(jsonBuilder.Length
    - 1, 1);
    jsonBuilder.Append(
    "]");
    jsonBuilder.Append(
    "}");
    return jsonBuilder.ToString();
    }

    #endregion dataTable转换成Json格式

    #region DataSet转换成Json格式
    /// <summary>
    /// DataSet转换成Json格式
    /// </summary>
    /// <param name="ds">DataSet</param>
    /// <returns></returns>
    public static string Dataset2Json(DataSet ds)
    {
    StringBuilder json
    = new StringBuilder();

    foreach (DataTable dt in ds.Tables)
    {
    json.Append(
    "{\"");
    json.Append(dt.TableName);
    json.Append(
    "\":");
    json.Append(DataTable2Json(dt));
    json.Append(
    "}");
    }
    return json.ToString();
    }
    #endregion

    使用时要加以注意。

     


    【孟子E章】
    2011年8月12日 4:42
    版主
  • 也可以这样

    JavaScript 调用 ASP.NET WebService 的简单方法

    客户端 JavaScript 调用 ASP.NET WebService 的方法除了采用 WebServer.htc 和 构造 SOAPAction 的方法外,下面介绍一个采用 Ajax 调用的简单方法,并且可以传递参数。其实,ASP.NET WebService 就是一个网站,所以,Request 对象是可用的,这样,传递参数就很容易了。下面是一个WebService1.asmx的代码

    ASMX 代码
    <%@ WebService Language="C#" CodeBehind="WebService1.asmx.cs" Class="WebService1" %>

     

    C# 代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    using System.Data;

    /// <summary>
    /// Summary description for WebService1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo
    = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(
    false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    // [System.Web.Script.Services.ScriptService]
    public class WebService1 : System.Web.Services.WebService
    {
    [WebMethod]
    // 字符串返回测试
    public string GetServerTime()
    {
    return "当前服务器时间:" + DateTime.Now.ToString();
    }

    [WebMethod]
    // long 类型返回测试
    public long GetServerTimeTicks()
    {
    return DateTime.Now.Ticks;
    }

    [WebMethod]
    // Datatable返回测试
    public DataTable GetTestDataTable()
    {
    DataTable dt
    = new DataTable("TestTable");
    DataRow dr;
    dt.Columns.Add(
    new DataColumn("id", typeof(Int32)));
    dt.Columns.Add(
    new DataColumn("text", typeof(string)));
    for (int i = 0; i < 6; i++)
    {
    dr
    = dt.NewRow();
    dr[
    0] = i;
    dr[
    1] = "列表项目 " + i.ToString();
    dt.Rows.Add(dr);
    }
    return dt;
    }

    [WebMethod]
    // List 类型测试
    public List<User> GetTestUser()
    {
    //传递参数传测试
    string param = this.Context.Request.QueryString["param"];
    if (param == null) param= this.Context.Request.Form["param1"];
    List
    <User> u_list = new List<User>();
    for (int i = 0; i < 10; i++)
    {
    User u
    = new User();
    u.Name
    = "LoginName" + i.ToString() + " param = " + param;
    u.Title
    = "孟宪会" + i.ToString();
    u_list.Add(u);
    }
    return u_list;
    }

    //定义一个对象 User
    public class User
    {
    public String Name { get; set; }
    public String Title { get; set; }
    }
    }

    客户端调用的代码:

    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 runat="server">
    <title>JavaScript 调用 ASP.NET Web 服务测试</title>
    <script type="text/javascript">
    var xmlHttp = null;
    function createXMLHttpRequest() {
    try {
    if (window.XMLHttpRequest)
    xmlHttp
    = new XMLHttpRequest();
    else if (window.ActiveXObject)
    xmlHttp
    = new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (ex) { }
    }

    function AsynRequest() {
    createXMLHttpRequest();
    if (xmlHttp == null) {
    alert(
    "不能创建 XmlHttpRequest 对象");
    return;
    }
    xmlHttp.open(
    "GET", "WebService1.asmx/GetTestUser?param=net_lover", true);
    xmlHttp.setRequestHeader(
    "Connection", "close");
    xmlHttp.onreadystatechange
    = function () {
    if (xmlHttp.readyState == 4) {
    if (xmlHttp.status == 200) {
    var userList = xmlHttp.responseXML.getElementsByTagName("User");
    for (i = 0; i < userList.length; i++) {
    document.getElementById(
    "get1").innerHTML += userList[i].getElementsByTagName("Name")[0].firstChild.nodeValue + "";
    document.getElementById(
    "get1").innerHTML += userList[i].getElementsByTagName("Title")[0].firstChild.nodeValue + "<br/>";
    }
    }
    }
    };
    xmlHttp.send();
    }

    function AsynPostRequest() {
    createXMLHttpRequest();
    if (xmlHttp == null) {
    alert(
    "不能创建 XmlHttpRequest 对象");
    return;
    }
    var data = "param1=abc";
    xmlHttp.open(
    "POST", "WebService1.asmx/GetTestUser?t=" + Date.parse(new Date()), true);
    xmlHttp.setRequestHeader(
    "Content-type", "application/x-www-form-urlencoded");
    xmlHttp.setRequestHeader(
    "Content-length", data.length);
    xmlHttp.setRequestHeader(
    "Connection", "close");
    xmlHttp.onreadystatechange
    = function () {
    if (xmlHttp.readyState == 4) {
    if (xmlHttp.status == 200) {
    var userList = xmlHttp.responseXML.getElementsByTagName("User");
    for (i = 0; i < userList.length; i++) {
    document.getElementById(
    "post1").innerHTML += userList[i].getElementsByTagName("Name")[0].firstChild.nodeValue + "";
    document.getElementById(
    "post1").innerHTML += userList[i].getElementsByTagName("Title")[0].firstChild.nodeValue + "<br/>";
    }
    }
    }
    };
    xmlHttp.send(data);
    }
    </script>
    </head>
    <body>
    <input type="button" value="GET 方法调用" onclick="AsynRequest()" />
    <input type="button" value="POST方法调用" onclick="AsynPostRequest()" />
    <div id="get1"></div>
    <div id="post1"></div>
    </body>
    </html>

    需要注意的是:使用此方法需要在web.config里加入以下的配置:

    web.config 代码
    <system.web>
    <webServices>
    <protocols>
    <add name = "HttpPost" />
    <add name = "HttpGet" />
    </protocols>
    </webServices>
    </system.web>

    另外,也可以采用ASP.NET内置的方法进行调用,方法如下:

    ASPX 代码
    <%@ Page Language="C#" %>
    <script runat="server">
    public class User
    {
    public String UserName { set; get; }
    public Int32 Count { set; get; }
    public User() { }
    }
    [System.Web.Services.WebMethod]
    [System.Web.Script.Services.ScriptMethod]
    public static List
    <User> GetUsers(int count)
    {
    List
    <User> p = new List<User>();
    User x
    = new User();
    x.UserName
    = "AA";
    x.Count
    = 20;
    p.Add(x);

    x
    = new User();
    x.UserName
    = "AA";
    x.Count
    = count;
    p.Add(x);
    return p;
    }
    </script>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
    <script type="text/javascript">
    function GetData() {
    PageMethods.GetUsers((
    new Date()).getSeconds(), OnGetProductsComplete);
    }
    function OnGetProductsComplete(result) {
    for (i = 0; i < result.length; i++) {
    alert(result[i].UserName
    + " = " + result[i].Count);
    }
    }
    </script>
    </head>
    <body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" />
    <input id="Button1" type="button" value="测试" onclick="GetData()" />
    </form>
    </body>
    </html>
    这里需要配置
    Web.config 文件,可以启用 HTTP GET 和 HTTP POST。以下配置同时启用了 HTTP GET 和 HTTP POST:
    <configuration>
      <system.web>
      <webServices>
        <protocols>
          <add name="HttpGet"/>
          <add name="HttpPost"/>
        </protocols>
      </webServices>
      </system.web>
    </configuration>

    【孟子E章】
    2011年8月12日 4:44
    版主