WebApi2属性路由继承了控制器

时间:2014-07-25 14:34:21

标签: c# asp.net routing asp.net-web-api asp.net-web-api2

我正在尝试使用基本控制器创建基本的REST api,如下所示:

基类:

public abstract class WebApiEntityController<TEntity> : ApiController
    where TEntity : EntityBase<TEntity, int>
{
    private readonly IRepository<TEntity> _repository; 
    protected WebApiEntityController(IRepository<TEntity> repository)
    {
        _repository = repository;
    }

    [Route("")]
    [WebApiUnitOfWork]
    public HttpResponseMessage Get()
    {
        return Request.CreateResponse(HttpStatusCode.OK, _repository.ToList());
    }
    [..........]

派生类:

[RoutePrefix("api/TimesheetTask")]
public class TimesheetTaskController : WebApiEntityController<TimesheetTask>
{
    private readonly IRepository<TimesheetTask> _timeSheetTaskRepository;

    public TimesheetTaskController(IRepository<TimesheetTask> timeSheetTaskRepository) : base(timeSheetTaskRepository)
    {
        _timeSheetTaskRepository = timeSheetTaskRepository;
    }
}

但是在路线〜/ api / TimesheetTask /上调用GET导致找不到404。

根据this回答,属性路由不能被继承。所以我的问题是,如何在不必复制和粘贴代码的情况下为所有域模型编写一致的API?

我知道我可以使用此配置进行约定路由:

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

但是我必须指定操作,我的端点将是

/api/{controller]/Get
/api/{controller]/Post

我不希望如此。我也可以删除routeTemplate的{action}部分,但是我将如何路由到自定义操作?

如果有人可以提供帮助,那将不胜感激。此外,我的域模型API的下一步将涉及支持查询,这很容易变得复杂。有没有为您生成这些路线的图书馆?如果有人能帮我找到这样的图书馆,我将不胜感激。

1 个答案:

答案 0 :(得分:7)

您引用的答案已更新。从WebApi 2.2开始,他们创建了一个扩展点,以允许您想要的功能。 属性路径可以继承,但您需要对其进行配置。我对基本API控制器有相同的要求,并且在搜索后遇到了你引用的相同答案。

.NET WebAPI Attribute Routing and inheritance

您需要覆盖DefaultDirectRoutePrivider

public class WebApiCustomDirectRouteProvider : DefaultDirectRouteProvider {
    protected override System.Collections.Generic.IReadOnlyList<IDirectRouteFactory>
        GetActionRouteFactories(System.Web.Http.Controllers.HttpActionDescriptor actionDescriptor) {
        // inherit route attributes decorated on base class controller's actions
        return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>(inherit: true);
    }
}

完成后,您需要在web api配置中配置它

public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        .....
        // Attribute routing. (with inheritance)
        config.MapHttpAttributeRoutes(new WebApiCustomDirectRouteProvider());
        ....
    }
}