Model binding new Datatables 1.10 parameters

前端 未结 6 1409
南方客
南方客 2021-02-01 16:44

In Datatables 1.10 the ajax server side parameters changed from

public class DataTableParamModel
{ 
    public string sEcho{ get; set; }
    public string sSearc         


        
相关标签:
6条回答
  • 2021-02-01 17:24

    The full server side binding implementation can be found here. I ran into a similar issue and this was how I went about solving it.

    0 讨论(0)
  • 2021-02-01 17:25

    Give this a try @shoe: datatables-mvc project: https://github.com/ALMMa/datatables-mvc

    0 讨论(0)
  • 2021-02-01 17:31

    Here is a model binder and class that will bind these new parameters...

    Parameter Model:

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

    Model Binder:

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

    Usage:

    MyController.cs

    public JsonResult DataTablesList(DTParameterModel model)
    {
        ...
    }
    

    MVC6

    If you're going to MVC6 you no longer need the model binder as MVC6 includes a JQueryFormValueProvider into the default model binder that can bind these values.

    The model classes themselves may still be useful, however.

    There is a bug to be fixed in 2.1.0 that doesn't allow binding for HttpGet but still works for HttpPost

    0 讨论(0)
  • 2021-02-01 17:32

    Know this post is 2 years old but to those who want to use this with ASP.Net Core MVC 6. This is the converted/ upgraded answer provided by @Shoe

    Model Binder:

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

    Parameter Model:

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

    Again all credit goes to @Shoe for original post.

    0 讨论(0)
  • 2021-02-01 17:41

    I changed my javascript to use the legacy ajax params option which uses the old parameters to send to the server. This is done through $.fn.dataTable.ext.legacy.ajax = true; so now my code becomes something like...

    $.fn.dataTable.ext.legacy.ajax = true;
    var datatable = $('#data-table').DataTable({
        "processing": true,
        "serverSide": true,
        "ajax": "MyController/AjaxHandlerPaging",
        "pageLength": 25,
        "order": [[2, 'desc']],
        "columns": []
    });
    
    0 讨论(0)
  • 2021-02-01 17:48

    I ran into the same issue when moving to 1.10. Basically, I changed my parameter class like this (getting rid of the unsupported parameters):

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

    In my controller, I get the search value, sort order, and sort column like this:

            var searchString = Request["search[value]"];
            var sortColumnIndex = Convert.ToInt32(Request["order[0][column]"]);
            var sortDirection = Request["order[0][dir]"]; // asc or desc
    
    0 讨论(0)
提交回复
热议问题