Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web Api: recommended way to return json string

I've got a couple of services which already receive a json string (not an object) that must be returned to the client. Currently, I'm creating the HttpResponseMessage explicitly and setting its Content property to the json string which the service receives:

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

Now, is there a better way of doing this with the new IHttpActionResult? Using the Content or Ok method ends up wrapping the json string with quotes, which is not what I want.

Any feedback?

like image 660
Luis Abreu Avatar asked Nov 27 '16 19:11

Luis Abreu


Video Answer


2 Answers

Create custom implementation. The framework is extensible via the IHttpActionResult.

The following creates a custom result and extension method...

public static class JsonStringResultExtension {
   public static CustomJsonStringResult JsonString(this ApiController controller, string jsonContent, HttpStatusCode statusCode = HttpStatusCode.OK) {
        var result = new CustomJsonStringResult(controller.Request, statusCode, jsonContent);
        return result;
    }

    public class CustomJsonStringResult : IHttpActionResult {
        private string json;
        private HttpStatusCode statusCode;
        private HttpRequestMessage request;

        public CustomJsonStringResult(HttpRequestMessage httpRequestMessage, HttpStatusCode statusCode = HttpStatusCode.OK, string json = "") {
            this.request = httpRequestMessage;
            this.json = json;
            this.statusCode = statusCode;
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) {
            return Task.FromResult(Execute());
        }

        private HttpResponseMessage Execute() {
            var response = request.CreateResponse(statusCode);
            response.Content = new StringContent(json, Encoding.UTF8, "application/json");
            return response;
        }
    }
}

...that can then be applied to ApiController derived classes. Greatly simplifying previous calls to

return this.JsonString(jsonUtilizadores); //defaults to 200 OK

or with desired HTTP status code

return this.JsonString(jsonUtilizadores, HttpStatusCode.BadRequest);
like image 115
Nkosi Avatar answered Sep 16 '22 17:09

Nkosi


Set your Web Api to return JSON Format:

    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        // Force to ignore Request Content Type Header and reply only JSON
        config.Formatters.Clear();
        config.Formatters.Add(new JsonMediaTypeFormatter());

        var corsAttr = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(corsAttr);
    }

and then return response like this:

        [HttpGet]
    [Route("{taskId}/list")]
    public IHttpActionResult GetTaskDocuments(string taskId)
    {
        var docs = repository.getTaskDocuments(taskId);
        if (docs != null)
        {
            return Ok(docs);
        }
        else
        {
            return Ok(new ResponseStatus() { Status = Constants.RESPONSE_FAIL, Message = repository.LastErrorMsg });
        }
    }

Where ResponseStatus is next class:

 public class ResponseStatus
    {
        public string Status { get; set; }
        public string Message { get; set; }
    }
like image 34
Samvel Petrosov Avatar answered Sep 16 '22 17:09

Samvel Petrosov