模型绑定新的 Datatables 1.10 参数
Posted
技术标签:
【中文标题】模型绑定新的 Datatables 1.10 参数【英文标题】:Model binding new Datatables 1.10 parameters 【发布时间】:2014-06-23 11:59:41 【问题描述】:在 Datatables 1.10 中,ajax 服务器端参数从
public class DataTableParamModel
public string sEcho get; set;
public string sSearch get; set;
public int iDisplayLength get; set;
public int iDisplayStart get; set;
public int iColumns get; set;
public int iSortingCols get; set;
public string sColumns get; set;
到(API 这里http://datatables.net/manual/server-side)
columns[i][data]
columns[i][name]
columns[i][orderable]
columns[i][search][regex]
columns[i][search][value]
columns[i][searchable]
...
draw
length
order[i][column]
order[i][dir]
...
search[regex]
search[value]
start
有些容易绑定
public class DataTableParamModel
public string draw get; set;
public int length get; set;
public int start get; set;
但新的数组格式看起来很棘手。
映射新参数格式的合适模型是什么?
【问题讨论】:
【参考方案1】:这是一个模型绑定器和将绑定这些新参数的类...
参数型号:
[ModelBinder(typeof(DTModelBinder))]
public class DTParameterModel
/// <summary>
/// Draw counter. This is used by DataTables to ensure that the Ajax returns from
/// server-side processing requests are drawn in sequence by DataTables
/// </summary>
public int Draw get; set;
/// <summary>
/// Paging first record indicator. This is the start point in the current data set
/// (0 index based - i.e. 0 is the first record)
/// </summary>
public int Start get; set;
/// <summary>
/// Number of records that the table can display in the current draw. It is expected
/// that the number of records returned will be equal to this number, unless the
/// server has fewer records to return. Note that this can be -1 to indicate that
/// all records should be returned (although that negates any benefits of
/// server-side processing!)
/// </summary>
public int Length get; set;
/// <summary>
/// Global Search for the table
/// </summary>
public DTSearch Search get; set;
/// <summary>
/// Collection of all column indexes and their sort directions
/// </summary>
public IEnumerable<DTOrder> Order get; set;
/// <summary>
/// Collection of all columns in the table
/// </summary>
public IEnumerable<DTColumn> Columns get; set;
/// <summary>
/// Represents search values entered into the table
/// </summary>
public sealed class DTSearch
/// <summary>
/// Global search value. To be applied to all columns which have searchable as true
/// </summary>
public string Value get; set;
/// <summary>
/// true if the global filter should be treated as a regular expression for advanced
/// searching, false otherwise. Note that normally server-side processing scripts
/// will not perform regular expression searching for performance reasons on large
/// data sets, but it is technically possible and at the discretion of your script
/// </summary>
public bool Regex get; set;
/// <summary>
/// Represents a column and it's order direction
/// </summary>
public sealed class DTOrder
/// <summary>
/// Column to which ordering should be applied. This is an index reference to the
/// columns array of information that is also submitted to the server
/// </summary>
public int Column get; set;
/// <summary>
/// Ordering direction for this column. It will be asc or desc to indicate ascending
/// ordering or descending ordering, respectively
/// </summary>
public string Dir get; set;
/// <summary>
/// Represents an individual column in the table
/// </summary>
public sealed class DTColumn
/// <summary>
/// Column's data source
/// </summary>
public string Data get; set;
/// <summary>
/// Column's name
/// </summary>
public string Name get; set;
/// <summary>
/// Flag to indicate if this column is orderable (true) or not (false)
/// </summary>
public bool Orderable get; set;
/// <summary>
/// Flag to indicate if this column is searchable (true) or not (false)
/// </summary>
public bool Searchable get; set;
/// <summary>
/// Search to apply to this specific column.
/// </summary>
public DTSearch Search get; set;
模型绑定器:
/// <summary>
/// Model Binder for DTParameterModel (DataTables)
/// </summary>
public class DTModelBinder : DefaultModelBinder
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
base.BindModel(controllerContext, bindingContext);
var request = controllerContext.HttpContext.Request;
// Retrieve request data
var draw = Convert.ToInt32(request["draw"]);
var start = Convert.ToInt32(request["start"]);
var length = Convert.ToInt32(request["length"]);
// Search
var search = new DTSearch
Value = request["search[value]"],
Regex = Convert.ToBoolean(request["search[regex]"])
;
// Order
var o = 0;
var order = new List<DTOrder>();
while (request["order[" + o + "][column]"] != null)
order.Add(new DTOrder
Column = Convert.ToInt32(request["order[" + o + "][column]"]),
Dir = request["order[" + o + "][dir]"]
);
o++;
// Columns
var c = 0;
var columns = new List<DTColumn>();
while (request["columns[" + c + "][name]"] != null)
columns.Add(new DTColumn
Data = request["columns[" + c + "][data]"],
Name = request["columns[" + c + "][name]"],
Orderable = Convert.ToBoolean(request["columns[" + c + "][orderable]"]),
Searchable = Convert.ToBoolean(request["columns[" + c + "][searchable]"]),
Search = new DTSearch
Value = request["columns[" + c + "][search][value]"],
Regex = Convert.ToBoolean(request["columns[" + c + "][search][regex]"])
);
c++;
return new DTParameterModel
Draw = draw,
Start = start,
Length = length,
Search = search,
Order = order,
Columns = columns
;
用法:
MyController.cs
public JsonResult DataTablesList(DTParameterModel model)
...
MVC6
如果您打算使用 MVC6,则不再需要模型绑定器,因为 MVC6 将 JQueryFormValueProvider 包含在可以绑定这些值的默认模型绑定器中。
不过,模型类本身可能仍然有用。
有一个bug 将在 2.1.0 中修复,它不允许绑定 HttpGet 但仍然适用于 HttpPost
【讨论】:
这段代码非常棒,为我节省了大量时间!您还需要在应用程序启动代码中添加一些内容:ModelBinders.Binders.Add(typeof(DTParameterModel), new DTModelBinder()); @user2320070 不客气。我还添加了一个使用部分。 +1,很棒的代码!我的两分钱,为了更好的可移植性,你可以在不改变 Global.asax.cs 的情况下实现它:在public class DTParameterModel
上方添加[ModelBinder(typeof(DTModelBinder))]
。那么,MyController.cs 方法可以只是:public JsonResult DataTablesList(DTParameterModel model)
。顺便说一句,您的 DTColumn 类缺少一个属性:public bool Searchable get; set;
(reference)。
开启上帝模式 +100000
您先生是救生员!一整天都在找这个。谢谢!【参考方案2】:
试试这个@shoe:datatables-mvc project:https://github.com/ALMMa/datatables-mvc
【讨论】:
它适用于模型活页夹,完全没有问题。现在只是用 EF 实现排序【参考方案3】:我更改了我的 javascript 以使用旧的 ajax 参数选项,该选项使用旧参数发送到服务器。这是通过$.fn.dataTable.ext.legacy.ajax = true;
完成的,所以现在我的代码变成了...
$.fn.dataTable.ext.legacy.ajax = true;
var datatable = $('#data-table').DataTable(
"processing": true,
"serverSide": true,
"ajax": "MyController/AjaxHandlerPaging",
"pageLength": 25,
"order": [[2, 'desc']],
"columns": []
);
【讨论】:
【参考方案4】:知道这篇文章已经有 2 年历史了,但是对于那些想要将其与 ASP.Net Core MVC 6 一起使用的人。这是@Shoe 提供的转换/升级答案
模型绑定器:
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace TrackingAndTraining.Models
/// <summary>
/// Model Binder for DTParameterModel (DataTables)
/// </summary>
public class DTModelBinder : IModelBinder
public Task BindModelAsync(ModelBindingContext bindingContext)
var request = bindingContext.ActionContext.HttpContext.Request.Form;
// Retrieve request data
var draw = Convert.ToInt32(request["draw"]);
var start = Convert.ToInt32(request["start"]);
var length = Convert.ToInt32(request["length"]);
// Search
var search = new DTSearch
Value = request["search[value]"],
Regex = Convert.ToBoolean(request["search[regex]"])
;
// Order
var o = 0;
var order = new List<DTOrder>();
while (!string.IsNullOrEmpty(request["order[" + o + "][column]"]))
order.Add(new DTOrder
Column = Convert.ToInt32(request["order[" + o + "][column]"]),
Dir = request["order[" + o + "][dir]"]
);
o++;
// Columns
var c = 0;
var columns = new List<DTColumn>();
while (!string.IsNullOrEmpty(request["columns[" + c + "][name]"]))
columns.Add(new DTColumn
Data = request["columns[" + c + "][data]"],
Name = request["columns[" + c + "][name]"],
Orderable = Convert.ToBoolean(request["columns[" + c + "][orderable]"]),
Searchable = Convert.ToBoolean(request["columns[" + c + "][searchable]"]),
Search = new DTSearch
Value = request["columns[" + c + "][search][value]"],
Regex = Convert.ToBoolean(request["columns[" + c + "][search][regex]"])
);
c++;
var result = new DTParameterModel
Draw = draw,
Start = start,
Length = length,
Search = search,
Order = order,
Columns = columns
;
bindingContext.Result = ModelBindingResult.Success(result);
return TaskCache.CompletedTask;
参数型号:
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace TrackingAndTraining.Models
[ModelBinder(BinderType = typeof(DTModelBinder))]
public class DTParameterModel
/// <summary>
/// Draw counter. This is used by DataTables to ensure that the Ajax returns from
/// server-side processing requests are drawn in sequence by DataTables
/// </summary>
public int Draw get; set;
/// <summary>
/// Paging first record indicator. This is the start point in the current data set
/// (0 index based - i.e. 0 is the first record)
/// </summary>
public int Start get; set;
/// <summary>
/// Number of records that the table can display in the current draw. It is expected
/// that the number of records returned will be equal to this number, unless the
/// server has fewer records to return. Note that this can be -1 to indicate that
/// all records should be returned (although that negates any benefits of
/// server-side processing!)
/// </summary>
public int Length get; set;
/// <summary>
/// Global Search for the table
/// </summary>
public DTSearch Search get; set;
/// <summary>
/// Collection of all column indexes and their sort directions
/// </summary>
public List<DTOrder> Order get; set;
/// <summary>
/// Collection of all columns in the table
/// </summary>
public List<DTColumn> Columns get; set;
/// <summary>
/// Represents search values entered into the table
/// </summary>
public sealed class DTSearch
/// <summary>
/// Global search value. To be applied to all columns which have searchable as true
/// </summary>
public string Value get; set;
/// <summary>
/// true if the global filter should be treated as a regular expression for advanced
/// searching, false otherwise. Note that normally server-side processing scripts
/// will not perform regular expression searching for performance reasons on large
/// data sets, but it is technically possible and at the discretion of your script
/// </summary>
public bool Regex get; set;
/// <summary>
/// Represents a column and it's order direction
/// </summary>
public sealed class DTOrder
/// <summary>
/// Column to which ordering should be applied. This is an index reference to the
/// columns array of information that is also submitted to the server
/// </summary>
public int Column get; set;
/// <summary>
/// Ordering direction for this column. It will be asc or desc to indicate ascending
/// ordering or descending ordering, respectively
/// </summary>
public string Dir get; set;
/// <summary>
/// Represents an individual column in the table
/// </summary>
public sealed class DTColumn
/// <summary>
/// Column's data source
/// </summary>
public string Data get; set;
/// <summary>
/// Column's name
/// </summary>
public string Name get; set;
/// <summary>
/// Flag to indicate if this column is orderable (true) or not (false)
/// </summary>
public bool Orderable get; set;
/// <summary>
/// Flag to indicate if this column is searchable (true) or not (false)
/// </summary>
public bool Searchable get; set;
/// <summary>
/// Search to apply to this specific column.
/// </summary>
public DTSearch Search get; set;
再次感谢 @Shoe 的原始帖子。
【讨论】:
您不需要 MVC6 的模型绑定器,因为它现在包含一个可以转换这些值的提供程序。见here 我已经使用了这个功能,但这不需要你维护发送的字段的名称,作为你的对象中的属性名称吗?并且任何特殊条件都必须放在这些属性的 getter 中。我更喜欢为此使用模型活页夹,可能只是我。 mvc6 中的默认模型绑定器将绑定 jquery 格式数据表使用的只是在我为 mvc5 编写的模型绑定器上。您可能仍然会发现数据表模型很有用,但如果您的意图只是绑定数据表,则不再需要像以前那样自定义绑定器。【参考方案5】:我在迁移到 1.10 时遇到了同样的问题。基本上,我改变了我的参数类(摆脱不支持的参数):
public class jQueryDataTableParamModel
/// <summary>
/// Request sequence number sent by DataTable,
/// same value must be returned in response
/// </summary>
public string draw get; set;
/// <summary>
/// Number of records that should be shown in table
/// </summary>
public int length get; set;
/// <summary>
/// First record that should be shown(used for paging)
/// </summary>
public int start get; set;
在我的控制器中,我得到搜索值、排序顺序和排序列,如下所示:
var searchString = Request["search[value]"];
var sortColumnIndex = Convert.ToInt32(Request["order[0][column]"]);
var sortDirection = Request["order[0][dir]"]; // asc or desc
【讨论】:
【参考方案6】:可以在here 找到完整的服务器端绑定实现。我遇到了类似的问题,这就是我解决它的方法。
【讨论】:
以上是关于模型绑定新的 Datatables 1.10 参数的主要内容,如果未能解决你的问题,请参考以下文章
确定 DataTables 是不是在 1.10 版中完成。有回调吗?
如何在DataTables 1.10中使用JQuery DataTables“input”插件
如何使用 jQuery.dataTables 1.10 向 ASP.NET WebMethod 后端发送和接收 JSON?