EvilDr EvilDr - 8 days ago 6
C# Question

Return json representations of data from WebAPI without strongly-typed IEnumerable

Having read a ton of different solutions and trying out different approaches (here, here, here, here, here), I am getting different (and unexpected) results from an API controller.

I need to return a datatable expressed as JSON, via a web api controller:

[IdentityBasicAuthentication]
[Authorize]
[RequireHttps]
[Route("Reports/Report1")]
public HttpResponseMessage Get()
{
DataTable dt = MyDAL.GetDataTable();
if(someValidationFailed){
Request.CreateResponse(HttpStatusCode.BadRequest, "Friendly error here");
}
return Request.CreateResponse(HttpStatusCode.OK, Newtonsoft.Json.JsonConvert.SerializeObject(dt));
}


In Fiddler, the output appears to be encoded into an escaped string:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

"[{\"Site\":\"Headquarters\",\"Department\":\"HR\",\"FirstName\":\"Bob\",\"MiddleName\":null,\"Surname\":\"Fern\",\"EmployeeNumber\":\"444\"},
{\"Site\":\"Headquarters\",\"Department\":\"HR\",\"FirstName\":\"Alice\",\"MiddleName\":null,\"Surname\":\"Smith\",\"EmployeeNumber\":\"769\"}]"


However, the goal is to output plain Json (or XML if the client requests it):

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[{"Site":"Headquarters","Department":"HR","FirstName":"Bob","MiddleName":null,"Surname":"Fern","EmployeeNumber":"444"},
{"Site":"Headquarters","Department":"HR","FirstName":"Alice","MiddleName":null,"Surname":"Smith","EmployeeNumber":"769"}]


Is there any way to do this without creating an
IEnumerable<Person>
object? The reason is that this class is specific to this one method. I also don't want to use a StringBuilder, because the DataTable may be extremely large and I've seen memory exceptions thrown previously.

I'm new to WebAPI, so the answer may be really simple, but a code sample I can ask further questions on would be very helpful.

Answer

Web API handles serialization for you, so you do not need to call JsonConvert.SerializeObject. That is why you are getting an escaped string as your output value. Just pass the datatable directly to CreateResponse. Web API will turn it into JSON or XML for you depending on what was sent in the Accept header of the request. (It uses Json.Net under the covers.)

return Request.CreateResponse(HttpStatusCode.OK, dt);