web-dev-qa-db-ja.com

新しいDatatables 1.10パラメータをモデルバインドする

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; }
}

to(API Here 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; }
}

しかし、新しい配列フォーマットは注意が必要です。

新しいパラメーター形式をマップするための新しい適切なモデルは何ですか?

25
Shoe

古いパラメーターを使用してサーバーに送信するレガシーajax paramsオプションを使用するようにJavaScriptを変更しました。これは$.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": []
});
5
Shoe

これらは、これらの新しいパラメーターをバインドするモデルバインダーとクラスです...

パラメータモデル:

[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 が含まれているため、モデルバインダーは不要です。

ただし、モデルクラス自体は引き続き有用です。

2.1.0で修正される bug があり、HttpGetのバインドは許可されていませんが、HttpPostで機能します

34
Shoe

これを試してください@shoe: datatables-mvc projecthttps://github.com/ALMMa/datatables-mvc

7
dalcam

この投稿は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 に送られます。

4
Shane Gardner

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
3
steveareeno

完全なサーバー側バインディングの実装は here にあります。私は同様の問題に遭遇し、これが私がそれを解決しようとした方法でした。

0
Obaigbona Joel