属性路由和继承

属性路由和继承

问题描述:

我正在考虑使用基本控制器的想法,该基本控制器使用通用存储库为我的API控制器提供基本的CRUD方法,这样我就不必在每个新控制器中重复相同的基本代码.但是,当路由属性在基本控制器中时,就遇到了无法识别路由属性的问题.为了确切说明我遇到的问题,我创建了一个非常简单的WebAPI控制器.

I am playing around with the idea of having a base controller that uses a generic repository to provide the basic CRUD methods for my API controllers so that I don't have to duplicate the same basic code in each new controller. But am running into problems with the routing attribute being recognized when it's in the base controller. To show exactly what the problem I'm having I've created a really simple WebAPI controller.

当我在主控制器中有一个Get方法并且它直接从ApiController继承时,我没有任何问题,并且可以按预期工作.

When I have a Get method in the main Controller and it inherits from the ApiController directly I don't have any problems and this works as expected.

[RoutePrefix("admin/test")]
public class TestController : ApiController
{
    [Route("{id:int:min(1)}")]
    public string Get(int id)
    {
        return "Success";
    }
}

当我将Get方法移动到基本控制器中时,它将返回404页的内容.

When I move the Get method into a base controller it is returning the contents of the 404 page.

[RoutePrefix("admin/test")]
public class TestController : TestBaseController
{

}

public class TestBaseController : ApiController
{
    [Route("{id:int:min(1)}")]
    public string Get(int id)
    {
        return "Success";
    }
}

一些更有趣的笔记:

  • 我可以在GET /Test/1*问操作.因此它仍基于默认路由来查找它.

  • I can access the action at GET /Test/1. So it is finding it based on the default route still.

当我尝试访问POST /admin/test时,它返回以下JSON

When I try to access POST /admin/test, it returns the following JSON

{ 消息":未找到与请求URI相匹配的HTTP资源' http://test.com/admin/测试'.", "MessageDetail":未找到与名为'admin'的控制器匹配的类型. }

{ "Message":"No HTTP resource was found that matches the request URI 'http://test.com/admin/test'.", "MessageDetail":"No type was found that matches the controller named 'admin'." }

有人知道从基本控制器获取路由以使用属性的方法吗?

Does anyone know of a way to get the routing to work with attributes from a base controller?

属性路由不能被继承.这是一个经过深思熟虑的设计决定.我们感觉不对,也没有看到有效的方案来继承它们.

Attribute routes cannot be inherited. This was a deliberate design decision. We didn't feel right and didn't see valid scenarios where it would make sense to inherit them.

您能否给出一个更现实的方案,以了解在哪里使用它?

Could you give a more realistic scenario as to where you would want to use this?

[更新(2014年3月24日)]
在即将发布的5.2版本的MVC Web API中,将有一个称为System.Web.Http.Routing.IDirectRouteProvider的扩展点,您可以通过该扩展点启用要在此处查找的继承方案.您可以使用最新的夜间构建版本自行尝试(有关如何使用夜间构建版本的文档,请参见 此处 )

[Update(3/24/2014)]
In the upcoming 5.2 release of MVC Web API, there is going to be an extensibility point called System.Web.Http.Routing.IDirectRouteProvider through which you can enable the inheritance scenario that you are looking for here. You could try this yourself using the latest night builds(documentation on how to use night builds is here)

[更新(2014年7月31日)]
在Web API 2.2版本中如何完成此操作的示例:

[Update(7/31/2014)]
Example of how this can be done in Web API 2.2 release:

config.MapHttpAttributeRoutes(new CustomDirectRouteProvider());

//---------

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