【问题标题】:Set status-code and content in webapi在 webapi 中设置状态码和内容
【发布时间】:2017-09-06 08:02:16
【问题描述】:

我想通过设置状态码获得一个漂亮而简单的 API,并获得 swagger (swashbuckle) 的文档

首先,我的控制器看起来像这样:

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();
        }
    }
}

一切正常,Swagger 以 json 格式显示结果。问题是,我无法设置状态码(例如,如果数据库错误,我可以设置为 Err 500 或 s.th.)。

Here 我读到了,为了设置状态码,我们需要返回一个HttpResponseMessage

所以我修改了我的代码:

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);
        }
    }
}

现在,状态码设置正确,但是swagger没有显示任何结果。

所以,我认为这可能是一个招摇的问题。

下一步是使用 Chromes Boomerang-Plugin 测试 API,但相同: Status-Code 为 304,但正文(结果/内容)为空:

肯定有结果:

关于如何使用 HttpResponseMessage 正确设置正文的任何​​想法? 或者,关于如何在返回值为例如时在 api 方法中设置状态代码的任何想法List&lt;Value&gt;?

【问题讨论】:

    标签: c# asp.net-web-api http-status-codes


    【解决方案1】:

    起初,HTTP 状态码 304 没有正文。 304 响应不得包含消息正文,因此始终以标头字段后的第一个空行终止。

    只需更改状态码即可。

    【讨论】:

    • 是的,这也是个问题。
    • @MatthiasBurger 这是主要问题;)请参阅我对我的回答的评论
    • @its_time_for_weekend 该死的你们俩都是对的。刚刚用 304 测试了你的解决方案,但它没有用。太好了,今天学到了一些东西。
    【解决方案2】:

    Rawitas Krungkaews 的回答部分正确。

    但是,您应该使用通用的ObjectContent 而不是StringContent

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

    参数Default是MediaTypeFormatter。我认为你可以在你的类中声明它:

    private static readonly MediaTypeFormatter DefaultJsonFormatter 
        = new JsonMediaTypeFormatter();
    

    【讨论】:

    • 这非常有效。但仍然不知道为什么CreateResponse 不起作用。
    • 猜猜你想设置的HttpStatusCode 不是正确的。看看HttpStatusCode.NotModified:The contents of the resource are not transferred的文档。如果一切正常并且您返回数据,只需给它一个HttpStatusCode.OKOK indicates that the request succeeded and that the requested information is in the response - 无需告诉别人,当您请求 GET 时没有任何修改。看,我将状态码(从 Rawitas 答案复制)更改为 Redirect。也许它因此而起作用
    【解决方案3】:
    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;
    

    【讨论】:

    • 谢谢,但序列化不是一个选项。恕我直言,在这里使用 Json.Net 不是正确的解决方案。 text/html 也是错误的。返回格式是 json,而不是 html。
    • 你可以试试这个。您只需将内容类型更改为“application/json”即可。
    猜你喜欢
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 2017-09-19
    • 2020-06-24
    相关资源
    最近更新 更多