繁体   English   中英

对于某些方法,基于属性的 webapi2 路由返回 404

[英]Attribute based webapi2 routing returns 404 for some methods

我目前正在开发一个从 Webapi 升级到 Webapi2 的项目。 部分转换包括切换到使用基于属性的路由。

我已经在 Global.asax 中适当地设置了我的路线(如下)

 GlobalConfiguration.Configure(config => config.MapHttpAttributeRoutes());

并删除了之前的路由配置。

我已经用适当的System.Web.Http.RouteAttributeSystem.Web.Http.RoutePrefixAttribute属性装饰了我所有的 API 控制器。

如果我使用调试器检查System.Web.Http.GlobalConfiguration.Configuration.Routes ,我可以看到我所有预期的路由都在集合中注册。 同样,在包含的生成的Webapi 帮助页面文档中也可以使用适当的路由。

尽管一切似乎都设置正确,但我的很多 REST 调用都会导致来自服务器的 404 not found 响应。

我发现了一些特定于 GET 方法的显着相似之处(这是我迄今为止测试过的所有内容)

  • 如果一个方法接受 0 个参数,它将失败
  • 如果路由覆盖前缀,它将失败
  • 如果一个方法接受一个字符串参数,它很可能会成功
  • 返回类型似乎没有影响
  • 命名路线似乎没有影响
  • 订购路线似乎没有影响
  • 重命名底层方法似乎没有影响

值得注意的是,我的 API 控制器出现在一个单独的区域,但考虑到某些路由确实有效,我不认为这是手头的问题。

非功能性方法调用示例

[RoutePrefix("api/postman")]
public class PostmanApiController : ApiController
{
    ...
    [HttpGet]
    [Route("all", Name = "GetPostmanCollection")]
    [ResponseType(typeof (PostmanCollectionGet))]
    public IHttpActionResult GetPostmanCollection()
    {
        return Ok(...);
    }
    ...
}

我希望这可以通过http://[application-root]/api/postman/all

有趣的是,打电话给

Url.Link("GetPostmanCollection", null)

将返回上述预期网址

同一控制器中方法调用的一个非常相似的示例,其中一些有效,一些无效。

[RoutePrefix("api/machine")]
public class MachineApiController : ApiController
{
    ...
    [HttpGet]
    [Route("byowner/{owner}", Name = "GetPostmanCollection")]
    public IEnumerable<string> GetByOwner([FromUri] string owner)
    {
        ...
    }
    ...

    [HttpGet]
    [Route("~/api/oses/{osType}")]
    public IEnumerable<OsAndVersionGet> GetOSes([FromUri] string osType)
    {
        ...
    }
    ...
}

调用http://[application-root]/api/machineby/ownername成功而http://[application-root]/api/oses/osType失败。

我一直在戳这个太久了,知道问题是什么吗?

任何ASP.NET MVC 路由注册之前,检查您是否通过MapHttpAttributeRoutes方法配置了MapHttpAttributeRoutes

根据微软关于MVC 和 Web API 中属性路由的 CodePlex 条目,设计部分指出:

在大多数情况下,首先调用 MapHttpAttributeRoutes 或 MapMvcAttributeRoutes,以便在全局路由之前注册属性路由(因此有机会取代全局路由)。 对属性路由控制器的请求也将被过滤为仅源自属性路由的请求。

因此,在Global.asax (或注册路由的地方)内调用:

GlobalConfiguration.Configure(c => c.MapHttpAttributeRoutes()); // http routes
RouteTable.Routes.MapRoute(...); // mvc routes

就我而言,这是一个愚蠢的错误,我发布此信息是为了让我身后犯同样错误的人可以在他们检查量子级别的其他所有内容之前阅读此内容。

我的错误是,我的控制器名称没有以Controller一词结尾。

新年快乐

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM