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
.
IHttpActionResult contains a single method, ExecuteAsync, which asynchronously creates an HttpResponseMessage instance. If a controller action returns an IHttpActionResult, Web API calls the ExecuteAsync method to create an HttpResponseMessage. Then it converts the HttpResponseMessage into an HTTP response message.
It is a high-level API that provides immutable object models for JSON object and array structures. These JSON structures are represented as object models using the Java types JsonObject and JsonArray .
You can create your own IHttpActionResult class instance to return the JSON and a method in your controller or base controller class to utilize it.
Create the IHttpActionResult instance that sets the content and status code:
public class JsonTextActionResult : IHttpActionResult
{
public HttpRequestMessage Request { get; }
public string JsonText { get; }
public JsonTextActionResult(HttpRequestMessage request, string jsonText)
{
Request = request;
JsonText = jsonText;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Execute());
}
public HttpResponseMessage Execute()
{
var response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(JsonText, Encoding.UTF8, "application/json");
return response;
}
}
Add a method to your controller to create the result. Here is a Web API example:
public class MyApiController : ApiController
{
protected internal virtual JsonTextActionResult JsonText(string jsonText)
{
return new JsonTextActionResult(Request, jsonText);
}
[HttpGet]
public IHttpActionResult GetJson()
{
string json = GetSomeJsonText();
return JsonText(json);
}
}
Another recommendation is as below;
var json = JToken.FromObject(yourObject);
return Ok(json);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With