Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Using DataTables with Web API Part 2: Making a POST Request

0.00/5 (No votes)
24 Nov 2016 1  
How to use DataTables with Web API Part 2: Making a POST request

This is part 2 of a 4-part series on using DataTables with WebAPI. Check out the other parts here:

So far, we’ve looked at hooking up DataTables to a Web API Controller via a simple GET request. Is that the best way to make our server side call though? We’ve seen a couple of problems with that approach. Anyone with the know-how could spy on the data as we send it across. If we want to show more columns, we’ll push the URL length towards that maximum. Time for plan B.

Plan B involves a small change to our client code. Instead of making a GET request, we’ll make a POST request instead.

If you haven't done so yet, grab the code from the previous article: Making a simple GET Request. Open up the Index view in Visual Studio (Views/Home/Index.cshtml) and scroll down to the scripts section. We're changing the AJAX method from GET (the default) to POST. It now looks like this:

"ajax": {
    "url": "/api/customerSearch",
    "method": "POST" // << add this new attribute here
},

If we now fire up the page in a browser, we get the old error alert again. If we examine what's happened within Developer Tools, we'll see a 405 error (method not allowed).

This is because our Web API Controller has a Get method, but needs a Post method. Let's fix that now. Open up the CustomerSearchController and change the method name to Post. You can remove the FromUri attribute too. Why? Because the data is now coming from the request body rather than the URI. Here's the new method:

public IHttpActionResult Post(SearchRequest request)
{
    var allCustomers = JsonConvert.DeserializeObject<CustomerData> (CustomerData);
    var response = new CustomerSearchResponse
    {
        Data = allCustomers.Data,
        Draw = request.Draw,
        RecordsFiltered = allCustomers.Data.Count,
        RecordsTotal = allCustomers.Data.Count
    };
    return Ok(response);
}

Because we’re using POST this time, we can take advantage of model binding. We can create a set of classes that mirror the structure we see in that URL. We’ll still use the same SearchRequest in our Controller. Let’s modify the SearchRequest a little and add some new classes:

public class SearchRequest
{
    public int Draw { get; set; }
    public int Start { get; set; }
    public int Length { get; set; }
    public ColumnRequestItem[] Columns { get; set; }
    public OrderRequestItem[] Order { get; set; }
    public SearchRequestItem Search { get; set; }
}

public class ColumnRequestItem
{
    public string Data { get; set; }
    public string Name { get; set; }
    public bool Searchable { get; set; }
    public bool Orderable { get; set; }
    public SearchRequestItem Search { get; set; }
}

public class OrderRequestItem
{
    public int Column { get; set; }
    public string Dir { get; set; }
}

public class SearchRequestItem
{
    public string Value { get; set; }
    public bool Regex { get; set; }
}

What’s going on here? Let’s remind ourselves of the URL that we saw in the previous article:

http://localhost:56835/api/customerSearch?draw=1&columns[0][data]=companyName&columns[0][name]=&columns[0][searchable]=true&columns[0][orderable]=true&columns[0][search][value]=&columns[0][search][regex]=false&columns[1][data]=address&columns[1][name]=&columns[1][searchable]=true&columns[1][orderable]=true&columns[1][search][value]=&columns[1][search][regex]=false&columns[2][data]=postcode&columns[2][name]=&columns[2][searchable]=true&columns[2][orderable]=true&columns[2][search][value]=&columns[2][search][regex]=false&columns[3][data]=telephone&columns[3][name]=&columns[3][searchable]=true&columns[3][orderable]=true&columns[3][search][value]=&columns[3][search][regex]=false&order[0][column]=0&order[0][dir]=asc&start=0&length=10&search[value]=&search[regex]=false&_=1479364345110

We can tell that the columns and order items are arrays in the URL. The [0] just after columns or order tells us this. Search, on the other hand, doesn’t have an index. It just has value and regex properties. We can call the classes whatever we like. All the model binder cares about is that we have properties with the names it expects to find.

We need an array called Columns and an array called Order. We need an object called Search and a property on the request called Draw. If we add anything else, it won’t contain any data. Things will still work, though. Likewise, if we miss out any properties on our classes, we won’t get that data. Things will still work though. Now, we could create a custom model binder for this. I’d rather create the classes manually in this example so we can see what’s going on.

And that's all there is to it. We've added the scaffolding for paging, sorting and searching. In the next article, we'll build on this and add paging, sorting and search capabilities to our table.

View original article

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here