新文章 网摘 文章 随笔 日记

如何使用 WebAPI 2 返回自定义 HTTP 状态代码

在开发 RESTful API 时,我们有时需要返回一个未包含在 MicrosoftHttpStatusCode枚举中的 HTTP 状态代码。例如,HTTP 423(锁定)等就是这种情况。这篇文章将给你一个关于如何返回这样一个自定义 HTTP 代码的例子。

在此处查看本机支持的 ​​HTTP 状态代码。

假设我们有以下简单的控制器,它提供了基于订单 ID 执行订单的可能性。

[RoutePrefix("api/v1/order-mgmt")]
public class OrderController : ApiController
{
    // ...

    [HttpGet, Route("execute")]
    public IHttpActionResult Execute(string orderid)
    {
        if (string.IsNullOrEmpty(orderid))
        {
            // HTTP 400
            return BadRequest("No value for parameter orderid provided");
        }
       
        if (someService.IsLocked())
        {
            // HTTP 423
            return ???
        }

        // ...

        // HTTP 200
        return Ok("Everything fine!");
    }
}
1234567891011121314151617181920212223242526

由于我们在这里使用属性路由,因此Execute(string orderid)可以通过 URL访问操作http://localhost:port/api/v1/order-mgmt/execute?orderid=<orderid-string>

一般来说,最好返回一个IHttpActionResultover anHttpResponseMessage.它提供了几个好处,例如:

  • 简化控制器的单元测试
  • 将用于创建 HTTP 响应的通用逻辑移动到单独的类中
  • 通过隐藏构建响应的低级细节,使控制器操作的意图更清晰

更多信息可以在这里找到。

someService.IsLocked()那么我们现在如何能够在返回时返回HTTP 423true呢?基本上有两种情况:

  1. 不带消息返回 HTTP 423 就足够了
  2. 您想返回 HTTP 423 并包含一条消息

对于第一个场景,我们只需要返回return new StatusCode((HttpStatusCode) 423);,我们就完成了!然而,对于第二种情况,我们需要自己实现IHttpActionResult这是我解决它的方法。

public class Locked : IHttpActionResult
{
    private readonly string message;
    private readonly HttpRequestMessage request;
 
    public Locked(string message, HttpRequestMessage request)
    {
        this.message = message;
        this.request = request;
    }
 
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage
        {
            StatusCode = (HttpStatusCode) 423,
            RequestMessage = this.request,
            Content = new StringContent(this.message)
        };
 
        return Task.FromResult(response);
    }
}
1234567891011121314151617181920212223

此实现允许我们返回带有消息的 HTTP 423。它可以按如下方式使用:

[RoutePrefix("api/v1/order-mgmt")]
public class OrderController : ApiController
{
    // ...
    [HttpGet, Route("execute")]
    public IHttpActionResult Execute(string orderid)
    {
        if (string.IsNullOrEmpty(orderid))
        {
            // HTTP 400
            return BadRequest("No value for parameter orderid provided");
        }
       
        if (someService.IsLocked())
        {
            // HTTP 423
            return new Locked("The resource is currently locked!"); 
        }
       
        // ...
       
        // HTTP 200
        return Ok("Everything fine!");
    }
}

https://www.azureblue.io/how-to-return-a-custom-http-status-code-using-webapi-2/
posted @ 2022-08-03 13:57  岭南春  阅读(334)  评论(0)    收藏  举报