2014-07-25 144 views
4

我试图创建基本的REST API与基本控制器,像这样:WebApi2属性继承路由控制器

基类:

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; 
    } 
} 

但调用GET路由〜/ api/TimesheetTask /结果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的下一步将涉及支持查询,并且这可能很容易变得复杂。有没有一个库为你生成这些路线?如果任何人都可以帮我找到这样的图书馆,将不胜感激。

回答

5

您引用的答案已经更新。从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()); 
     .... 
    } 
}