WebApi2属性路由继承了控制器

Des*_*Lee 4 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());
    }
    [..........]
Run Code Online (Sandbox Code Playgroud)

派生类:

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

    public TimesheetTaskController(IRepository<TimesheetTask> timeSheetTaskRepository) : base(timeSheetTaskRepository)
    {
        _timeSheetTaskRepository = timeSheetTaskRepository;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

根据这个答案,属性路由不能被继承.所以我的问题是,如何为所有域模型编写一致的API而无需复制和粘贴代码?

我知道我可以使用这种配置进行常规路由:

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

但是我必须指定行动,而我的终点将是

/api/{controller]/Get
/api/{controller]/Post
Run Code Online (Sandbox Code Playgroud)

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

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

Nko*_*osi 7

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

.NET WebAPI属性路由和继承

你需要覆盖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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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