WebAPI with POST instead of GET
WebAPI with POST instead of GET

Spent the last couple of days trying my first server side DataTable w/ WebAPI 2.0. I installed DataTables.AspNet.WebApi2. I worked the example at GitHub into my existing project. I got the example code working.
First big issue was it was passing too much data in the URL for GET. I followed the docs here and changed to POST: https://datatables.net/examples/server_side/post.html
As long as I limit the table columns, it works with GET. When I change to POST, it hits the endpoint, but in "IDataTablesRequest request," request is always null. It's not with GET.
I dropped down to one column and hit the endpoint with GET and POST. The data it passes is:
Using POST (this is from the body and doesn't work):
draw=1&columns%5B0%5D%5Bdata%5D=orderNo&columns%5B0%5D%5Bname%5D=OrderNo&columns%5B0%5D%5Bsearchable%5D=false&columns%5B0%5D%5Borderable%5D=false&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&order%5B0%5D%5Bname%5D=OrderNo&start=0&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false
Using GET, from the URL (works):
draw=1&columns%5B0%5D%5Bdata%5D=orderNo&columns%5B0%5D%5Bname%5D=OrderNo&columns%5B0%5D%5Bsearchable%5D=false&columns%5B0%5D%5Borderable%5D=false&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&order%5B0%5D%5Bname%5D=OrderNo&start=0&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&_=1742406764085
The only thing I see different between the two is that GET added: &_=1742406764085
Is there anything else I should do when swapping from GET to POST? The link for the docs I posted makes it sound like all you have to do is change it to POST and it should work.
Thanks,
Answers
The
_
is an anti cache parameter for GET requests.Your server side script needs to be told to use the body parameters from the POST request if you change it to POST. What is your server side script?
Allan
That's easy. It's C#. I just change the decoration for my endpoint from
[HttpGet] to [HttpPost], which I did do.
The block of code I posted in my question that comes from the body, that was actually copied from an actual POST, so it's hitting the endpoint and getting far enough for me to capture the body. However, at my breakpoint, the request object (IDataTablesRequest request) is always null.
Usually when that happens, I mistyped a DTO object property or something similar. In this case, however, I would expect that if the IDataTablesRequest object works with GET, it would also work reading the same object from the body of a POST.
That's why I ended up asking if there was anything else on the client side I needed to do, other than following the instructions on the link in my question.
When I first moved the DataTables.AspNet.WebApi2 files into my project, I didn't register them in the Global.asax.cs file. This also causes the IDataTablesRequest object to always be null. When I got that worked out, GET started working immediately.
However, after too many columns, GET starts erroring out on me.
Got some time to work on it this afternoon, so I'm going to give it another go.
Thanks,
In further testing, I came up with this test. Without touching a thing on the client side, I made a test class with a property of "Draw" in it. When DataTables posts to the server, I can set a breakpoint, I get no errors, and I see that Draw = 1;
If I change back to this:
In both cases of the above, the client side is this:
Again, in cases similar to this, it's usually I typed a DTO object property wrong, or something similar. However, in this case, that's out of my control. I would assume what the client is sending is correct, since it works with GET.
Thanks,
AFAIK
IDataTablesRequest
is not something that is apart of Datatables. It looks likeIDataTablesRequest
is part of the ALMMa/datatables.aspnet package you linked to. Have you researched or asked in their issues section about the issue with it beingnull
? I'm not familair with the package but I suspect you will need to do something within their package to deal with the nullIDataTablesRequest
.EDIT: It does look like the developer is not maintaining the package anymore. See this issue.
Kevin
Very interesting. I converted the IDataTablesRequest interfaces to class files, the best I could, and I am able to POST it to the server and read the values.
Very weird that if I converted it to GET, the same controller works.
A ran across this SO thread. Not sure it applies to you but it show your not the only one running into this issue.
Kevin
Six hours later, I finally actually captured an actual error:
Newtonsoft.Json.JsonSerializationException: Could not create an instance of type DataTables.AspNet.Core.IDataTablesRequest. Type is an interface or abstract class and cannot be instantiated. Path 'draw', line 1, position 8.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)}
And if anyone needs to know how I got that, I had to put the [FromBody] in before it would show any error:
Set a breakpoint and view the ModelState. It only shows the errors when [FromBody] is added!
So, looking at the error, pretty much the answer is to register it properly in Global.asax.
I've already done that, because GET wasn't working until I did that.
Interesting - thank you for posting back your findings. I haven't used the third party
IDataTablesResponse
class before, so I can't help much in that regard I'm afriad.DtRequest
in my own library is similar, although it expects to be used in the method withRequest.Form
(or similar), rather than as a parameter to the method.Allan
[FromBody]
seems to think the body is JSON. But the body you've shown looks like a standardapplication/x-www-form-urlencoded
body.Do you have any global jQuery AJAX configuration that might be sending the wrong content-type header with the request?
Have a look at the headers of the request in your browser's dev tools network panel to see what content type is being sent.
Content-type: application/json; charset=utf-8.
So, with the [FromBody] attribute, it just mysteriously started working for me. Just to make sure I'm not crazy, I rebuilt my endpoint from the GitHub example I started with. I have made no other changes in my project, either. I changed zero on the client side. With [FromBody], the "request" object is no longer null. If I remove [FromBody], then it is null again.
I'll admit, I'm not a high level developer. I mainly do A LOT of database crud, and I keep it as simple as I can. But I've been at it long enough that I can say, something usually doesn't fix itself, especially after I've been working on it for two straight days.
Even if I get the table working the way I want, this all makes me nervous about trying to move this into production.
Looking through SO, I still don't quite understand the [FromBody] attribute. It seems redundant to [HttpPost], which means it's a POST and is going to use the request body.
Thanks,