65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 DataTables 与 Web API 第 1 部分:进行简单的 GET 请求

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (5投票s)

2016 年 11 月 19 日

CPOL

6分钟阅读

viewsIcon

37443

如何使用 datatables 与 Web API - 进行简单的 GET 请求。

多年来,我一直有这个需求

因此,我们有了一个仪表板,我们需要在表格中显示客户/用户/其他数据,以便我们可以搜索、排序、过滤,以及进行所有这些操作……

听起来很熟悉?好吧,我们可以有几种方法来处理这个问题。首先,我们可以手动完成所有工作。创建表格结构并从数据源绑定每一行。但这太费事了!我们需要某种帮助器或插件来让我们的生活更轻松。能够将我们普通的表格变成一个功能强大的搜索工具。

隆重推出 DataTables……

对于那些不知道的人来说,DataTables 是一个功能丰富的 jQuery 插件。它允许您将 HTML 表格连接到数据源。如果您想查看它,可以从 https://datatables.net.cn 下载。它具有大量有用的功能和设置,我们可以利用它们。在本文中,我们将研究如何向 Web API 服务发送 GET 请求并显示数据。在下一篇文章中,我们将研究改为发送 POST 请求时会发生什么。现在,让我们保持简单。

客户端代码

首先,我们将创建一个快速的 MVC 项目,其中包含一个将显示我们表格的视图。打开 Visual Studio 并创建一个新的 Web 应用程序。

Visual Studio new project window

此项目需要 Web API 和 MVC,但不需要身份验证)。使用这些选项

Visual Studio new project options window

在此示例中,我们将显示客户列表(姓名、地址、电话号码)。打开 Views/Home 文件夹中的 Index 视图,并添加一个具有以下结构的 HTML 表格

<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">Customers</h3>
    </div>
    <div class="panel-body">
        <table id="CustomersTable" class="table table-striped table-bordered table-hover responsive" width="100%">
            <thead class="thin-border-bottom">
            <tr>
                <th>Name</th>
                <th>Address</th>
                <th>Postcode</th>
                <th>Tel</th>
            </tr>
            </thead>
        </table>
    </div>
</div>

现在,添加 DataTables 脚本和样式的链接。暂时使用 DataTables CDN。打开 Views/Shared 中的 _Layout 页面。将链接标签放入页面的 head 部分,并将脚本标签放在脚本部分的正上方。

head 部分应如下所示

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width" />
  <title>@ViewBag.Title</title>
  @Styles.Render("~/Content/css")
  @Scripts.Render("~/bundles/modernizr")
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.css" />
</head>

脚本如下所示

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.js"></script>
@RenderSection("scripts", false)

DataTables 包含一个方便的 jQuery 插件,我们将使用它来激活我们的表格。我们将为其提供一个 URL,该 URL 将是我们的 Web API 服务的端点 (/api/CustomerSearch)。稍后我们将介绍这一点。这是我们需要的脚本。将此脚本部分放在 Index 视图的底部

@section scripts {
  <script>
    (function($) {
      var generateCustomerTable = $("#CustomerTable")
        .dataTable({
          "processing": true,
          "serverSide": true,
          "ajax": {
            "url": "/api/customerSearch"
          },
          "columns": [
            { "data": "companyName" }, { "data": "address" }, { "data": "postcode" },
            { "data": "telephone" }
          ],
          "language": {
            "emptyTable": "There are no customers at present.",
            "zeroRecords": "There were no matching customers found."
          },
          "searching": false,
          "ordering": true,
          "paging": true
        });
    })(jQuery);
  </script>
}

我们需要确保我们脚本中的 id(在本例中为 CustomerTable)与 HTML 中的表格 id 匹配。现在,当我们在浏览器中加载页面时,插件将向我们的 Web API 控制器发送一个 GET 请求。目前我们会收到 404 错误,但这给了我们一个机会来查看插件发出的调用。稍后我们将在 API 端使用查询字符串中的一些属性。您可以忽略出现的错误弹出窗口。这只是 DataTables 告诉我们 API 控制器尚不存在。我们稍后会修复它。

DataTables 会将哪些信息发送到服务器?

如果您使用的是 Chrome,按 F12 会打开开发者工具。然后您可以单击 Network 选项卡并按 api 进行筛选以查看调用

DataTables error browser window

让我们仔细看看那个 URL

https://:56835/api/customerSearch?draw=1&columns%5B0%5D%5Bdata%5D=companyName&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=address&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=postcode&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=telephone&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&start=0&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&_=1479364345110 

看起来很吓人,不是吗?别担心,它是经过编码的。在浏览器发出调用之前,它必须是这样的。我们做一些替换,使其更容易阅读。我们将 %5B 替换为 [,将 %5D 替换为 ]。现在它看起来是这样的

https://:56835/api/customerSearch?draw=1&columns[0][data]=companyName&columns[0][name]=&columns[0][searchable]=true&columns[0][orderable]=true&columns[0][search][value]=&columns[0][search][regex]=false&columns[1][data]=address&columns[1][name]=&columns[1][searchable]=true&columns[1][orderable]=true&columns[1][search][value]=&columns[1][search][regex]=false&columns[2][data]=postcode&columns[2][name]=&columns[2][searchable]=true&columns[2][orderable]=true&columns[2][search][value]=&columns[2][search][regex]=false&columns[3][data]=telephone&columns[3][name]=&columns[3][searchable]=true&columns[3][orderable]=true&columns[3][search][value]=&columns[3][search][regex]=false&order[0][column]=0&order[0][dir]=asc&start=0&length=10&search[value]=&search[regex]=false&_=1479364345110

这里有什么?首先,它包含大量关于我们表格列的信息(它是一个数组,因此有 [0] 等 - 我们将在下一篇文章中使用它)。它还包含对我们用于排序的列的引用。我们在末尾有分页和筛选信息(Start、Length 和 Search)。我们将在本系列的第 3 部分中介绍它们。

我们还有一个 Draw 计数器。这很重要,因为 DataTables 会跟踪重绘表格的次数。每次与表格交互时,DataTables 都会从服务器重新获取数据。它还会递增该计数器。当带有数据的调用返回时,Draw 参数需要具有相同的值,否则我们会收到错误。您可以在此处阅读有关参数的更多信息:DataTables: Server Side

关于使用 GET(而不是 POST)进行此请求有几点需要注意。它的安全性不如 POST,因为任何监视数据在传输过程中数据的人都可以读取和/或更改它。在我们的例子中,他们可能能够更改某些列的名称或其他内容。这并不是什么大问题。一个更大的问题是,这个查询字符串有 1038 个字符。浏览器支持的最大长度为 2048 个字符。如果我们需要在表格中显示更多列,它将在我们的查询字符串中添加更多参数。很快就会超过最大长度。不过,一开始,发送 GET 请求对我们来说很棒。它向我们展示了 DataTables 如何构建它发送的数据。我们将在另一边需要这些知识。现在让我们去那里。

服务器端代码

让我们向项目中添加一个 Web API 控制器。我们称之为 CustomerSearchController。我们还需要一些类来保存我们将要来回传递的数据。最终,我们的项目中会有这些文件

Visual Studio Controller file list

让我们首先看看数据类

public class SearchRequest
{
    public int Draw { get; set; }
}

public abstract class SearchDetail
{
}

public class CustomerSearchDetail : SearchDetail
{
    public string CompanyName { get; set; }
    public string Address { get; set; }
    public string Postcode { get; set; }
    public string Telephone { get; set; }
}

public abstract class SearchResponse<T> where T : SearchDetail
{
    public int Draw { get; set; }

    public int RecordsTotal { get; set; }

    public int RecordsFiltered { get; set; }

    public IList<T> Data { get; set; }
}

public class CustomerSearchResponse : SearchResponse<CustomerSearchDetail>
{
}

我暂时省略了 CustomerData.cs。在讨论 Controller 代码时,我会回到它。这里发生了什么?嗯,我们可以在 SearchRequestSearchResponse 上看到 Draw 属性。这会让 DataTables 满意。我们在 SearchResponse 上有两个计数器。它们告诉 DataTables 我们是否通过搜索过滤掉了任何结果。我们将在本系列的第 3 部分中介绍这一点。现在,它们都将包含总客户数。我们还使用一些泛型来控制 SearchResponseData 属性使用的类型。

Web API 服务本质上是 RESTful 的。我们发送的是 GET 请求,因此我们将在控制器中添加一个名为 Get 的方法。在下一篇文章中,我们将通过您猜到的 Post 方法添加 POST 支持。让我们现在看一下 Controller 代码

public class CustomerData
{
    public IList<CustomerSearchDetail> Data { get; set; }
}

public class CustomerSearchController : ApiController
{
    private const string CustomerData = @"
{
  ""Data"": [
    {
      ""CompanyName"": ""Microsoft"",
      ""Address"": ""1 Microsoft Way, London"",
      ""Postcode"": ""N1 1NN"",
      ""Telephone"": ""020 7100 1000""  
    },
    {
      ""CompanyName"": ""Nokia"",
      ""Address"": ""2 Nokia Way, London"",
      ""Postcode"": ""N2 2NN"",
      ""Telephone"": ""020 7200 2000""
    },
    {
      ""CompanyName"": ""Apple"",
      ""Address"": ""3 Apple Way, London"",
      ""Postcode"": ""N3 3NN"",
      ""Telephone"": ""020 7300 3000""
    },
    {
      ""CompanyName"": ""Google"",
      ""Address"": ""4 Google Way, London"",
      ""Postcode"": ""N4 4NN"",
      ""Telephone"": ""020 7400 4000""
    },
    {
      ""CompanyName"": ""Samsung"",
      ""Address"": ""5 Samsung Way, London"",
      ""Postcode"": ""N5 5NN"",
      ""Telephone"": ""020 7500 5000""
    }
  ] 
}";

    public IHttpActionResult Get([FromUri]SearchRequest request)
    {
        var allCustomers = JsonConvert.DeserializeObject<CustomerData>(CustomerData);
        var response = new CustomerSearchResponse
        {
            Data = allCustomers.Data,
            Draw = request.Draw,
            RecordsFiltered = allCustomers.Data.Count,
            RecordsTotal = allCustomers.Data.Count
        };
        return Ok(response);
    }
}

我们在这里所做的只是将一个 json 字符串转换为 CustomerData 对象。我们通过 DeserializeObject 方法使用了 Json.NET 库。如果这是一个生产系统,我们将从某种数据库中提取数据。但这对于我们的示例来说非常完美。CustomerData 对象具有与我们的 json 字符串中的结构匹配的结构。Json.NET 库将其转换为我们的代码可以使用的内容。

请求旁边的 FromUri 属性告诉我们的 Controller 尝试从 URL 中的 QueryString 数据创建 SearchRequest 对象。

如果我们在浏览器中重新加载页面,表格应该看起来像这样

DataTables final browser display window

它相当静态,但我们可以看到客户数据显示出来,并且行数准确。在系列的其余部分,我们将研究使用 Post 而不是 Get 来检索数据。我们还将研究搜索、分页和排序数据。

查看原文

© . All rights reserved.