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

本文关键字:webapi2 路由 返回 属性 方法 于某些 于属性 | 更新日期: 2023-09-27 17:58:55

我目前正在处理一个项目,该项目已从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未找到响应。

我发现了一些特定于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)

将返回上述预期的url

在同一个控制器中方法调用的一个非常相似的例子,其中有些可以工作,有些不可以。

[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没有成功。

我已经戳这个问题太久了,你知道问题可能是什么吗?

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

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

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

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

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

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

在我的情况下,这是一个愚蠢的错误,我发布这篇文章是为了让我后面犯同样错误的人在检查量子级别的其他内容之前可以阅读这篇文章。

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

新年快乐