创建新的IHttpActionResult操作结果方法

Int*_*pid 36 c# asp.net-web-api2

有没有办法可以使用新IHttpActionResult界面返回HttpStatusCode.NoContent响应消息?

我目前正在使用return new HttpResponseMessage( HttpStatusCode.NoContent ); 并希望将其转换为return NoContent();.

IHttpActionResult已经得到了Ok(),Conflict()并且NotFound()但是我找不到任何的Forbidden()NoContent()我需要在我的项目中使用.

添加其他结果类型有多容易?

Raf*_*oni 49

no-content结果没有方便的方法,因为默认情况下,当操作返回时void,响应将具有HTTP状态204.

如果您希望明确指出在操作上,您还可以StatusCode(HttpStatusCode.NoContent)从您的操作或a中返回

ResponseMessage(new HttpResponseMessage(HttpStatusCode.NoContent)).
Run Code Online (Sandbox Code Playgroud)

Unauthorized()方便方法为您提供401状态,因此对于Forbidden(403),您还必须使用StatusCode(HttpStatusCode.Forbidden)

ResponseMessage(new HttpResponseMessage(HttpStatusCode.Forbidden))
Run Code Online (Sandbox Code Playgroud)

  • 未经授权= 401.禁止= 403. (3认同)
  • 在某些情况下,返回`void`不是一个选项,因为您要在验证时使用BadRequest或其他状态代码进行响应,仅在成功时发送NoContent.返回`StatusCode(HttpStatusCode.NoContent)`为我解决了这个问题,它是一个更清晰的解决方案,接受了答案. (3认同)

Int*_*pid 24

我发现这个示例站点显示了如何添加自定义IHttpActionResult方法,并且我已经使用它来创建Forbidden()NoContent()方法取得了巨大成功.

public abstract class CommonApiController : ApiController
{
    public class ForbiddenResult : IHttpActionResult
    {
        private readonly HttpRequestMessage _request;
        private readonly string _reason;

        public ForbiddenResult(HttpRequestMessage request,string reason)
        {
            _request = request;
            _reason = reason;
        }

        public ForbiddenResult(HttpRequestMessage request)
        {
            _request = request;
            _reason = "Forbidden";
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = _request.CreateResponse(HttpStatusCode.Forbidden,_reason);
            return Task.FromResult(response);
        }
    }

    public class NoContentResult : IHttpActionResult
    {
        private readonly HttpRequestMessage _request;
        private readonly string _reason;

        public NoContentResult(HttpRequestMessage request,string reason)
        {
            _request = request;
            _reason = reason;
        }

        public NoContentResult(HttpRequestMessage request)
        {
            _request = request;
            _reason = "No Content";
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = _request.CreateResponse(HttpStatusCode.NoContent,_reason);
            return Task.FromResult(response);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我可以像这样使用它:

public class InvoiceController : CommonApiController
{
    public async Task<IHttpActionResult> Post([FromBody]Invoice invoice)
    {
        if(User.IsInRole("Readonly"))
        {
            return Forbidden();
        }

        // Rest of code

    }
}
Run Code Online (Sandbox Code Playgroud)


Asa*_*aum 8

我尝试了@Intrepid实现,但遇到了一些问题.我在这看到两个解决方案:

解决方案1: 部分:return Forbidden();不应该工作.

编译器无法识别这一点.

相反它应该是: return new ForbiddenResult(Request, "my reason");

更新1

解决方案2:

我认为这是@Interpid在实施中的意图,但他遗漏了一些东西.

为了使用return Forbidden();CommonApiController应该是返回自定义功能进行更新IHttpActionResultForbiddenNoContent

该类应如下所示:

public abstract class CommonApiController: ApiController {

    protected ForbiddenResult Forbidden() {
     return new ForbiddenResult(this.Request);
    }

    protected ForbiddenResult Forbidden(string reason) {
     return new ForbiddenResult(this.Request, reason);
    }

    protected NoContentResult NoContent() {
     return new NoContentResult(this.Request);
    }

    public class ForbiddenResult: IHttpActionResult {
     private readonly HttpRequestMessage _request;
     private readonly string _reason;

     public ForbiddenResult(HttpRequestMessage request, string reason) {
      _request = request;
      _reason = reason;
     }

     public ForbiddenResult(HttpRequestMessage request) {
      _request = request;
      _reason = "Forbidden";
     }

     public Task < HttpResponseMessage > ExecuteAsync(CancellationToken cancellationToken) {
      var response = _request.CreateResponse(HttpStatusCode.Forbidden, _reason);
      return Task.FromResult(response);
     }
    }

    public class NoContentResult: IHttpActionResult {
     private readonly HttpRequestMessage _request;
     private readonly string _reason;

     public NoContentResult(HttpRequestMessage request, string reason) {
      _request = request;
      _reason = reason;
     }

     public NoContentResult(HttpRequestMessage request) {
      _request = request;
      _reason = "No Content";
     }

     public Task < HttpResponseMessage > ExecuteAsync(CancellationToken cancellationToken) {
      var response = _request.CreateResponse(HttpStatusCode.NoContent, _reason);
      return Task.FromResult(response);
     }
    }
   }
Run Code Online (Sandbox Code Playgroud)

无论如何,如果我错了,@ Interpid的回答是正确的.我在这里错过了什么让他的实施工作?


小智 8

您现在可以使用以下(.Net 标准):

return StatusCode(HttpStatusCode.NoContent);
Run Code Online (Sandbox Code Playgroud)

或 (.Net Core 2.1+)

return NoContent();
Run Code Online (Sandbox Code Playgroud)