Web API 操作过滤器,用于处理空集和 404

本文关键字:处理 空集 用于 API 操作 过滤器 Web | 更新日期: 2023-09-27 18:32:35

我有一个控制器方法,它返回如下资源列表:

 [HttpGet, Route("events/{id:int}/rosters")]     
 public RosterExternalList List(int id, int page = 1, int pageSize = 50) {
    return Repository.GetRosters(id).ToExternal(page, pageSize);
 }

存储库方法是:

public IQueryable<EventRoster> GetRosters(int id) {
   return EventDBContext.EventRosters.Where(x => x.eventID == id).OrderBy(x => x.EventRosterID).AsQueryable();
}

对于多个列表方法,这是相同的模式。 问题是,当没有从数据库中检索到任何项目时,即使传入的 id 无效,api 也会发送一个具有空响应正文的 200。

我想要的是,如果id =无效,请发送适当的响应(404? 否则,如果 id 有效且没有记录,则发送正文为空的 200。

我的问题是 - 这是处理这个问题的正确方法吗? 这可以通过操作过滤器完成,以便在所有类似的方法中实现吗? 如何?

Web API 操作过滤器,用于处理空集和 404

可以使用这样的操作过滤器:

    public class EventsFilter : ActionFilterAttribute
    {
        public EventDBContext EventDBContext { get; set; }
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            bool exists = false;
            var routeData = actionContext.Request.GetRouteData();
            object value;
            if (routeData.Values.TryGetValue("id", out value))
            {
                int id;
                if (int.TryParse(value, out id))
                {
                    exists = EventDBContext.EventRosters.Where(x => x.eventID == id).Any();
                }
            }
            if (exists == false)
            {
                var response = actionContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, "Event not found");
                throw new HttpResponseException(response);       
            }
        }
    }

还需要配置依赖项解析程序以设置 EventDBContext 属性。

这是正确的方式吗?

这取决于您的解决方案设计:

  • 如果您的业务层是集成的并且依赖于 Web API(如您的示例中所示(,那么是的,这是要走的路。

  • 如果 Web API
  • (服务层(不是唯一使用业务层的人,则您可能希望避免在其他地方重复事件检查,并将其移动到比 Web API 操作筛选器更通用的类,并从业务层而不是 Web API 调用此类,以确保无论调用方如何, 您将始终检查事件是否存在。在该类中,您将抛出类似BusinessLogicNotFoundException的内容,其中包含有关事件的信息。在 Web API 上,您需要创建一个 ExceptionFilterAttribute 来处理BusinessLogicNotFoundException并创建适当的 404 响应。