【问题标题】:How to provide extra methods for returning IHttpActionResult?如何提供额外的方法来返回 IHttpActionResult?
【发布时间】:2017-05-31 16:05:17
【问题描述】:

我有一个 ApiController,它返回带有资源集合的 OkNegotiatedContentResult<T>,分页。自然会有更多返回分页集合的方法。

所有这些操作的结果中的content 大致如下:

  • 包含当前项目的 Data 属性
  • 带有分页元数据的 PagingMeta 属性,例如总页数和总项目数
  • PagingLinks 属性,包含指向第一页/上一页/下一页/最后一页的链接

我的后端返回一个自定义的PagedList<T> 对象,我还有另一个包含上述属性的PagedListResponse<T>。这是从一个到另一个的简单转换。

现在,在 Web API 中,ApiController 提供了几个方便的方法来返回 IHttpActionResult,例如:

  • Ok<T>(T value)
  • Content<T>(HttpStatusCode statusCode, T value)

我希望让控制器同样轻松地返回分页结果。

目前我有一个提供它的扩展方法,具有以下签名:

public static OkNegotiatedContentResult<PagedListResult<T>> OkPaged<T>(this ApiController controller, /* other parameters */)

“丑”是你只能通过包含this关键字来调用扩展方法:

return this.OkPaged(myResult);

我能看到的唯一其他选择是实现一个基本控制器类,但我通常会尽量避免这种继承结构,因为它们以后往往会变得麻烦。

ASP.NET 在扩展点方面提供了什么来做我想做的事?

【问题讨论】:

    标签: asp.net inheritance asp.net-web-api asp.net-web-api2


    【解决方案1】:

    您始终可以创建一个继承自 IHttpActionResult 的类并将其用作您的返回值,例如

    public class HttpStatusCodeResultWithContent<T> : IHttpActionResult
    {
        private readonly HttpRequestMessage httpRequestMessage;
    
        private readonly HttpStatusCode statusCode;
    
        public HttpStatusCodeResultWithContent(HttpRequestMessage httpRequestMessage, HttpStatusCode statusCode, T model)
        {
            this.httpRequestMessage = httpRequestMessage;
            this.statusCode = statusCode;
            ResponseModel = model;
        }
    
        public T ResponseModel { get; private set; }
    
        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = httpRequestMessage.CreateResponse(statusCode, ResponseModel);
            return Task.FromResult(response);
        }
    }
    

    这在 HttpStatusCodeResultWithContent 中为您提供了一个易于测试的类,它允许您返回具有任何 HTTP 状态代码的任何内容。

    然后从你的控制器代码中,

    var pagedListResult = someObject.GetPagedList();
    return new HttpStatusCodeResultWithContent<PagedListResult<T>(Request, HttpStatusCode.OK, pagedListResult);
    

    然后,如果您愿意,可以在 ApiController 上使用扩展方法来结束对此的访问 - 这几乎就是 ApiController 内部发生的所有事情,例如这是 ApiController 上的“Ok”方法的样子。

    protected internal virtual OkNegotiatedContentResult<T> Ok<T>(T content)
    {
        return new OkNegotiatedContentResult<T>(content, this);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-09
      • 1970-01-01
      • 2017-04-27
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多