1

I'm tying to get a nice and simple API with setting status-code and get the documentation of swagger (swashbuckle)

First, my controller looked like this:

public class ValuesController : ControllerBase
{
    [SwaggerResponse(HttpStatusCode.OK, Type = typeof(List<Value>))]
    [HttpGet, System.Web.Mvc.Route("api/values/")]
    public async Task<List<Value>> GetValues(HttpRequestMessage request)
    {
        using (DatabaseContext context = new DatabaseContext())
        {
            return await context.Values.Take(10).ToListAsync();
        }
    }
}

All fine, Swagger shows the result json-formatted. Problem is, I can't set the status code (like, if database-error I could set to Err 500 or s.th.).

Here I read, for setting a status code we need to return a HttpResponseMessage

So I modified my code:

public class ValuesController : ControllerBase
{
    [SwaggerResponse(HttpStatusCode.OK, Type = typeof(HttpResponseMessage))]
    [HttpGet, System.Web.Mvc.Route("api/values/")]
    public async Task<HttpResponseMessage> GetValues(HttpRequestMessage request)
    {
        using (DatabaseContext context = new DatabaseContext())
        {
            var valuesToReturn = await context.Values.Take(10).ToListAsync();
            return request.CreateResponse(HttpStatusCode.NotModified, valuesToReturn);
        }
    }
}

Now, the status code is set correctly, but swagger doesn't show any result.

enter image description here

So, I thought this maybe is a swagger-problem.

Next step was to test the API with Chromes Boomerang-Plugin, but same: Status-Code is 304, but the body (result/content) is empty:

enter image description here

There definitely is result: enter image description here

Any idea on how to set the body correctly with the HttpResponseMessage? Or, any idea on how to set the status code in the api-method when return value is e.g. List<Value>?

Matthias Burger
  • 5,549
  • 7
  • 49
  • 94

3 Answers3

3

At first the HTTP status code 304 doesn't have a body. The 304 response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields.

Just change the status code.

narekye
  • 114
  • 3
2

Rawitas Krungkaews answer is partly correct.

But, you should use the generic ObjectContent instead of StringContent:

var res = new HttpResponseMessage()
{
    Content = new ObjectContent<List<Value>>(valuesToReturn, DefaultJsonFormatter),
    StatusCode = HttpStatusCode.Redirect
};
return res;

The parameter Default is the MediaTypeFormatter. I think you can declare it in your class like:

private static readonly MediaTypeFormatter DefaultJsonFormatter 
    = new JsonMediaTypeFormatter();
  • This works perfectly. But still no idea why `CreateResponse` didn't work. – Matthias Burger Sep 06 '17 at 13:24
  • guess the `HttpStatusCode` you wanted to set is not the right one. Take a look at the documentation of `HttpStatusCode.NotModified`: `The contents of the resource are not transferred`. If everything works fine and you return data, just give it a `HttpStatusCode.OK`: `OK indicates that the request succeeded and that the requested information is in the response` - no need to tell someone, nothing was modified when you request a GET. And see, I changed the statuscode (copied from Rawitas answer) to `Redirect`. Maybe it worked due to this – its_time_for_weekend Sep 06 '17 at 13:42
0
var valuesToReturn = new List<string>();
valuesToReturn.Add("test01");
var res = new HttpResponseMessage()
{
    Content = new StringContent(JsonConvert.SerializeObject(valuesToReturn), Encoding.UTF8, "application/json"),
    StatusCode = HttpStatusCode.Redirect
};
return res;
Ray Krungkaew
  • 6,652
  • 1
  • 17
  • 28
  • thanks, but serializing is not an option. Imho, it can't be the correct solution to use Json.Net here. Also `text/html` is wrong. The return-format is json, not html. – Matthias Burger Sep 06 '17 at 08:30
  • You can try this. All you need to do is just change content type to "application/json". – Ray Krungkaew Sep 06 '17 at 08:46