.NET WebAPI属性路由和继承

Jef*_*ing 64 asp.net-web-api asp.net-web-api-routing

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

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

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

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

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

}

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

一些更有趣的笔记:

  • 我可以在GET/Test/1上访问该操作.所以它仍然基于默认路线找到它.

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

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

有没有人知道如何让路由使用基本控制器的属性?

Kir*_*lla 78

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

你能否给出一个更真实的场景,你想在哪里使用它?

[ 更新(2014年3月24日)]
在即将发布的MVC Web API的5.2版本中,将会有一个可扩展点,System.Web.Http.Routing.IDirectRouteProvider通过它可以启用您在此处寻找的继承方案.你可以自己尝试使用最新的夜间版本(关于如何使用夜间版本的文档在这里)

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我正在尝试做同样的事情 - 有一个基本的CRUD控制器,它使用通用服务接口处理所有基本的crud任务.这是一个非常逼真的场景.您对具有"基本控制器中的操作的特定路径模板"的用户的响应非常容易解决 - 不要从该基本控制器继承.你没有从这个设计决定中获得任何好处,并阻止了一些非常好的功能.对于这里的每一条评论,我确信还有数百人正在尝试做同样的事情.你们这里犯了一个错误.请修理它. (11认同)
  • 这就是我要玩的东西.我有一个通用的存储库,并打算创建一个RepositoryBaseApiController <T>,它加载了一个IRepository <T>,用于基本的CRUD操作.这样,如果我需要为实体提供一个真正简单的WebAPI,我可以创建一个SomeEntityController并从RepositoryBaseApiController继承<SomeEntity>,它将为我处理所有基础知识.我不必每次都创建动作,验证检查和路由.我会在主控制器上使用RoutePrefix(),但基本控制器将具有相对的Route (3认同)
  • 谢谢,Kiran.我开了一个问题.任何想要继承AttributeRouting的人都应该投票 - https://aspnetwebstack.codeplex.com/workitem/1688 (2认同)

Dej*_*jan 25

使用Web API 2.2,您可以:

public class BaseController : ApiController
{
    [Route("{id:int}")]
    public string Get(int id)
    {
        return "Success:" + id;
    }
}
[RoutePrefix("api/values")]
public class ValuesController : BaseController
{
}

config.MapHttpAttributeRoutes(new CustomDirectRouteProvider());
public class CustomDirectRouteProvider : DefaultDirectRouteProvider
{
    protected override IReadOnlyList<IDirectRouteFactory> 
    GetActionRouteFactories(HttpActionDescriptor actionDescriptor)
    {
        return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>
        (inherit: true);
    }
}
Run Code Online (Sandbox Code Playgroud)

如下所述:http://www.asp.net/web-api/overview/releases/whats-new-in-aspnet-web-api-22