2014-05-06 5 views
23

In Datentabellen 1.10 Ajax Serverseite Parameter geändert vonModell Bindung neue Datentabellen 1.10 Parameter

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

bis (API Hier 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 

Einige sind leicht zu binden

public class DataTableParamModel 
{ 
    public string draw { get; set; } 
    public int length{ get; set; } 
    public int start { get; set; } 
} 

Aber das neue Array-Format sieht schwierig aus.

Was ist das neue geeignete Modell, um das neue Parameterformat zuzuordnen?

Antwort

4

ich mein Javascript das Erbe Ajax params Option verwenden geändert, die die alten Parameter verwendet, um den Server zu senden. Dies geschieht durch $.fn.dataTable.ext.legacy.ajax = true; so jetzt mein Code wird so etwas wie ...

$.fn.dataTable.ext.legacy.ajax = true; 
var datatable = $('#data-table').DataTable({ 
    "processing": true, 
    "serverSide": true, 
    "ajax": "MyController/AjaxHandlerPaging", 
    "pageLength": 25, 
    "order": [[2, 'desc']], 
    "columns": [] 
}); 
3

ich in der gleichen Ausgabe lief, als bis 1,10 bewegen. Grundsätzlich änderte ich meine Parameter Klasse wie folgt (immer der nicht unterstützten Parameter rid):

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 meinem Controller, ich den Suchwert erhalten, Sortierreihenfolge und Sortierspalte wie folgt aus:

 var searchString = Request["search[value]"]; 
     var sortColumnIndex = Convert.ToInt32(Request["order[0][column]"]); 
     var sortDirection = Request["order[0][dir]"]; // asc or desc 
31

Hier ist ein Modell, Bindemittel und Klasse, die diese neuen Parameter binden ...

Parameter Modell:

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

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

Verbrauch:

MyController.cs

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

MVC6

Wenn du gehst Für MVC6 benötigen Sie den Modellbinder nicht mehr, da MVC6 eine JQueryFormValueProvider in den Standardmodellbinder enthält, der diese Werte binden kann.

Die Modellklassen selbst können jedoch immer noch nützlich sein.

Es gibt eine bug in 2.1.0 festgelegt werden, die nicht für HttpGet Bindung erlaubt, funktioniert aber immer noch für Httppost

+4

zu implementieren Dieser Code ist grandios und ersparte mir ein riesiges Stück Zeit! Sie müssen auch etwas zum Startup-Code der Anwendung hinzufügen: ModelBinders.Binders.Add (typeof (DTParameterModel), new DTModelBinder()); – user2320070

+1

@ user2320070 Gern geschehen. Ich habe auch einen Verwendungsabschnitt hinzugefügt. – Shoe

+0

Guter Code, vielen Dank für die Freigabe. – HolloW

0

Kennen Sie diesen Beitrag 2 Jahre alt, aber für diejenigen, die dies mit ASP verwenden möchten. Net Core MVC 6.Dies ist die konvertierte/ausgebaute Antwort zur Verfügung gestellt von @Shoe

Modell 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 Modell:

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

Wieder alle Kredite für Original-Beitrag zu @Shoe gehen.

+0

Sie sollten keinen Modellbinder für MVC6 benötigen, da dieser nun einen Anbieter enthält, der diese Werte übersetzen kann. Siehe [hier] (https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/JQueryFormValueProviderFactory.cs) – Shoe

+0

Ich habe diese Funktionalität verwendet, aber das erfordert dies nicht Sie pflegen die Namen der gesendeten Felder als Eigenschaftsnamen in Ihrem Objekt? Und alle besonderen Bedingungen müssten in den Getter dieser Eigenschaften gesetzt werden. Ich bevorzuge, ein Modellbinder dafür zu verwenden, kann nur ich sein. –

+0

Der Standard-Modellbinder in mvc6 wird das jquery-Format binden, das nur für den Modellbinder verwendet wird, den ich für mvc5 geschrieben habe. Sie könnten das Databildmodell immer noch nützlich finden, aber wenn Sie nur Databänder binden möchten, benötigen Sie keinen benutzerdefinierten Binder wie zuvor. – Shoe