.NET WebAPI属性路由和继承如何实现?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (13)

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

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

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

当我将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";
    }
}

一些更有趣的笔记:

  • 我可以在GET / Test / 1上访问该操作。所以它仍然基于默认路由来查找它。
  • 当我尝试访问POST / admin / test时,它返回以下JSON {“消息”:“没有HTTP资源发现该请求URI‘匹配http://test.com/admin/test ’。”,“MessageDetail”:“否型发现,命名为‘管理员’控制器相匹配。 “ }

有谁知道一种方法来让路由与来自基础控制器的属性一起工作吗?

提问于
用户回答回答于

属性路由不能被继承。这是一个故意的设计决定。我们感觉不对,并没有看到有效的场景,它们可以继承它们。

你可以给出一个更现实的情景,你想在哪里使用它? 在即将发布的MVC Web API的5.2版本中,将会有一个扩展点,System.Web.Http.Routing.IDirectRouteProvider通过它可以启用在此寻找的继承场景。你可以使用最新的夜间版本自己尝试一下(关于如何使用夜间版本的文档在这里) 在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);
    }
}
用户回答回答于

使用WebAPI 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);
    }
}

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

扫码关注云+社区