IHttpActionResult with JSON string

Viewed 27636

I have a method that originally returned an HttpResponseMessage and I'd like to convert this to return IHttpActionResult.

My problem is the current code is using JSON.Net to serialize a complex generic tree structure, which it does well using a custom JsonConverter I wrote (the code is working fine).

Here's what it returns:

    string json = NodeToJson(personNode);

    HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
    response.Content = new StringContent(json, Encoding.UTF8, "application/json");

    return response;

The NodeToJson method is where the custom converter comes into play ...

private static string NodeToJson(Node<Person> personNode) {

    var settings = new JsonSerializerSettings {
        Converters = new List<JsonConverter> { new OrgChartConverter() },
        Formatting = Formatting.Indented
    };

    return JsonConvert.SerializeObject(personNode, settings);

}

Note this returns a string, formatted as JSON.

If I switch this to IHttpActionResult, it seems to fail regardless of what I try. I can just leave it (it works) but I am supposed to be using best practices for this and IHttpActionResult seems to be what I should be using.

I have tried to return Json(json); but this results in invalid, unparsable JSON, presumably because it's trying to do a double conversion?

return Ok(json); results in the JSON string being wrapped in XML.

What is the right way to do this?

EDIT:

I have successfully converted every method in this project to use IHttpActionResult now except this particular method.

It's a serialization of a generic tree to JSON. Regardless of what approach I try, I get back invalid JSON. The HttpResponseMsessage approach works fine, but I can not get valid JSON back with IHttpActionResult.

8 Answers

Some of the solutions here are converting string to JSON, that's not necessary. You are just using computer resources for nothing.

// Instead of 
//    return Ok(jsonstring);
// do:
      HttpResponseMessage response = this.Request.CreateResponse(HttpStatusCode.OK);
      response.Content = new StringContent(jsonstring, Encoding.UTF8, "application/json");
      Request.RegisterForDispose(response); //To avoid the Pragma CA2000 warning
      return ResponseMessage(response);

Another solution At client side

You can make a small change to be prepared to receive a string and convert it if necessary. The code bellow is Javascript

    var data;
    if (typeof weapiresponse == "string")
        data = JSON.parse(weapiresponse);
    else
        data = weapiresponse;

For me, the only way to return an IHttpActionResult with the string content as Json in the following.

[HttpGet]
public IHttpActionResult ReturnStringAsJson()
{
    return this.ResponseMessage(new HttpResponseMessage
    {
        Content = new StringContent("[json string]"), 
        Encoding.UTF8, 
        "application/json"), 
    });
}
Related