.NET的WebAPI属性路由和继承

.NET的WebAPI属性路由和继承

问题描述:

我玩弄具有使用一个通用的存储库来为我的API控制器的基本CRUD方法,这样我就不必重复相同的基本code在每一个新的控制器的基础控制器的想法。但是,正在运行与路由属性问题,当它在基本控制器被认可。要显示正是我有我创建了一个非常简单的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 the 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";
    }
}

一些更有趣的注意事项:

Some more interesting notes:


  • 我可以在GET /测试/ 1访问的动作。因此,它是基于默认路由仍然找到它。

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

当我尝试访问POST /管理/测试它返回下面的JSON

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

{
消息:没有HTTP资源发现,请求URI http://test.com/admin/test '匹配。
MessageDetail:没有类型被发现,命名为管理员的控制器相匹配。
}

{ "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 ,通过它可以使继承场景,你正在寻找在这里。你可以使用最新的夜构建(文档了解如何使用夜间构建是here)

[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日)结果
这是如何在网络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);
    }
}