34

Problem:

  • jQuery DataTables server-side processing using ASP.NET WebForms.

Solution:

  • Darin Dimitrov answered the question using an example which pages and sorts, but doesn't do any searching. Here's my **basic** modification of his work to make searching work on his example:
public class Data : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        // Paging parameters:
        var iDisplayLength = int.Parse(context.Request["iDisplayLength"]);
        var iDisplayStart = int.Parse(context.Request["iDisplayStart"]);

        // Sorting parameters
        var iSortCol = int.Parse(context.Request["iSortCol_0"]);
        var iSortDir = context.Request["sSortDir_0"];

        // Search parameters
        var sSearch = context.Request["sSearch"];

        // Fetch the data from a repository (in my case in-memory)
        var persons = Person.GetPersons();

        // Define an order function based on the iSortCol parameter
        Func<Person, object> order = person => iSortCol == 0 ? (object) person.Id : person.Name;

        // Define the order direction based on the iSortDir parameter
        persons = "desc" == iSortDir ? persons.OrderByDescending(order) : persons.OrderBy(order);

        // prepare an anonymous object for JSON serialization
        var result = new
                         {
                             iTotalRecords = persons.Count(),
                             iTotalDisplayRecords = persons.Count(),
                             aaData = persons
                                 .Where(p => p.Name.Contains(sSearch))  // Search: Avoid Contains() in production
                                 .Where(p => p.Id.ToString().Contains(sSearch))
                                 .Select(p => new[] {p.Id.ToString(), p.Name})
                                 .Skip(iDisplayStart)   // Paging
                                 .Take(iDisplayLength)
                         };

        var serializer = new JavaScriptSerializer();
        var json = serializer.Serialize(result);
        context.Response.ContentType = "application/json";
        context.Response.Write(json);
    }

    public bool IsReusable { get { return false; } }
}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }

    public static IEnumerable<Person> GetPersons()
    {
        for (int i = 0; i < 57; i++)
        {
            yield return new Person { Id = i, Name = "name " + i };
        }
    }
}
rebelliard
  • 9,592
  • 6
  • 47
  • 80
  • I have implemented datatables all over my project in PHP, I had to create my own classes because that example isn't really useful outside of specific tasks (and it's kind hard to follow). You should be dealing with about 100 lines for the request and response of your class. I don't normally deal with ASP.net but I'll see if I can find something for you. – Incognito Aug 30 '10 at 13:24
  • I tested this code and realize that the paging and record count remain the same when you filter object. – zXSwordXz Nov 28 '16 at 12:52

5 Answers5

49

I wrote a simple example that should illustrate the idea.

Start by writing a generic handler for handling data on the server side (Data.ashx but this could be a web page, web service, anything server side script capable of returning JSON formated data):

public class Data : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        // Those parameters are sent by the plugin
        var iDisplayLength = int.Parse(context.Request["iDisplayLength"]);
        var iDisplayStart = int.Parse(context.Request["iDisplayStart"]);
        var iSortCol = int.Parse(context.Request["iSortCol_0"]);
        var iSortDir = context.Request["sSortDir_0"];

        // Fetch the data from a repository (in my case in-memory)
        var persons = Person.GetPersons();

        // Define an order function based on the iSortCol parameter
        Func<Person, object> order = p => 
        {
            if (iSortCol == 0) 
            { 
                return p.Id; 
            }
            return p.Name;
        };

        // Define the order direction based on the iSortDir parameter
        if ("desc" == iSortDir)
        {
            persons = persons.OrderByDescending(order);
        }
        else
        {
            persons = persons.OrderBy(order);
        }

        // prepare an anonymous object for JSON serialization
        var result = new
        {
            iTotalRecords = persons.Count(),
            iTotalDisplayRecords = persons.Count(),
            aaData = persons
                .Select(p => new[] { p.Id.ToString(), p.Name })
                .Skip(iDisplayStart)
                .Take(iDisplayLength)
        };

        var serializer = new JavaScriptSerializer();
        var json = serializer.Serialize(result);
        context.Response.ContentType = "application/json";
        context.Response.Write(json);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }

    public static IEnumerable<Person> GetPersons()
    {
        for (int i = 0; i < 57; i++)
        {
            yield return new Person
            {
                Id = i,
                Name = "name " + i
            };
        }
    }
}

And then a WebForm:

<%@ Page Title="Home Page" Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head id="Head1" runat="server">
    <title></title>
    <link rel="stylesheet" type="text/css" href="/styles/demo_table.css" /> 
    <script type="text/javascript" src="/scripts/jquery-1.4.1.js"></script>
    <script type="text/javascript" src="/scripts/jquery.dataTables.js"></script>
    <script type="text/javascript">
        $(function () {
            $('#example').dataTable({
                'bProcessing': true,
                'bServerSide': true,
                'sAjaxSource': '/data.ashx'
            });
        });
    </script>
</head>
<body>
    <form id="Form1" runat="server">
        <table cellpadding="0" cellspacing="0" border="0" class="display" id="example"> 
            <thead> 
            <tr> 
                <th>ID</th> 
                <th>Name</th> 
            </tr> 
            </thead> 
            <tbody> 
            <tr> 
                <td colspan="5" class="dataTables_empty">Loading data from server</td> 
            </tr> 
            </tbody> 
        </table>
    </form>
</body>
</html>

The example is oversimplified but I hope it will illustrate the basics on how to get stared.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Exactly the kick I needed. Many thanks. -- I have to add that this works as long as I rename your .ashx class to lowercase "data" (how it is used in the .aspx page). – rebelliard Aug 31 '10 at 00:26
  • You said that: "Start by writing a generic handler for handling data on the server side (Data.ashx but this could be a web page, web service, anything server side script capable of returning JSON formated data)". I don't want to use handlers, my projects have a lot of grid and I want to centralize them to a webservice. But how to handler the context from web service web method? – Vinh May 06 '11 at 09:11
  • @Vinh, what web service? Are you talking about a SOAP enabled service? – Darin Dimitrov May 06 '11 at 09:14
  • Hi @Darin, I mean something like this http://datatables.net/forums/comments.php?DiscussionID=2040 – Vinh May 17 '11 at 10:49
  • 1
    @DarinDimitrov You just saved a two months experienced bulgarian developer in the journey of completing his last assigned project. Thank you, tons. –  Jun 28 '12 at 14:52
  • 1
    Hey Peter, always glad when I could help fellow compatriots :-) – Darin Dimitrov Jun 28 '12 at 15:17
  • but if i want to use a search how can i do it? – Severiano Jan 28 '14 at 12:51
  • Thanks a lot! You made my day – Deise Vicentin Oct 14 '15 at 18:29
2

The example pages you listed actually sort, paginate, filter on initialization. Basically, you pass those data via query string.

Something like:

sAjaxSource": "../examples_support/server_processing.ashx?SortBy=FirstName&FilterBy=StackOverFlow"

Having said that, if you want to override some behavior or want to extend dataTable's functionaly, you have a few options: Extending dataTable functionality Customizing Scrolling

You can follow the above examples and customize them for Filtering, Sorting, and Pagination

Holystream
  • 962
  • 6
  • 12
1

I'm asp.Net developer... Please take in mind that .net developers are used to build web pages using .net controls, not javascript controls.

The difference is: an asp.net control is a server-side control, you manage it without writing javascript your self, but programming in C#/VB.net. The asp.net control automatically generates the client-side javascript control when the website runs.

It approach is more "modern" and really powerful.

So if you are a .net developer I suggest you to use this approach. If you are a javascript developer and you are building only the client-side interface of your application, probably you need a webService that provides the server-side data in XML format that you can call and read over HTTP. But, to "search", provide "pagination" and "sorting" via AJAX you need to develop server-side...

Fabio B.
  • 970
  • 2
  • 14
  • 29
  • I am aware of that, which is why I'm asking if anyone has succesfully returned XML/jSON data back to the jQuery datatable using ASP.NET. I too am a .NET developer and I can handle my way around doing this from scratch, but I'm first trying to see if someone has figured out datatables with .NET. :) – rebelliard Aug 20 '10 at 14:28
  • 1
    I bet it will run faster than .Net server control way. – maxisam Aug 06 '12 at 05:02
1

Maybe this could help? http://www.codeproject.com/KB/aspnet/ASPNET_DataTable_to_JSON.aspx

Fabio B.
  • 970
  • 2
  • 14
  • 29
1

http://naspinski.net/post/REAL-AJAX-with-AspNet-(not-AspNet-AJAX).aspx

This guy has made ajax work with asp.net and datatables.

Incognito
  • 20,537
  • 15
  • 80
  • 120
  • 1
    Shame that example doesn't use AJAX for paging: "What we are going to do will load all the data (which could be slower initially on large data sets)" – Ian Grainger Feb 28 '13 at 10:53