7

我目前正在从Webapi升级到Webapi2的项目上工作。部分转换包括切换到使用基于属性的路由。基于属性的webapi2路由为某些方法返回404

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

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

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

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

如果我用调试器检查System.Web.Http.GlobalConfiguration.Configuration.Routes我可以看到我所有的预期路由都在集合中注册。同样,如预期的那样,在包含的生成的Webapi Help Page文档中可以获得适当的路线。

即使所有的设置都正常,我的REST调用的很多次都会导致404未找到来自服务器的响应。

我发现特定于GET方法(这是所有我到目前为止测试)

  • 如果一个方法接受0参数它失败
  • 一些显着的相似之处如果路由覆盖前缀它失败
  • 如果一个方法需要一个字符串参数,它是可能成功
  • 返回S型EEMS有没有影响
  • 命名的路线似乎也没有影响
  • 订购的路线似乎也没有影响
  • 重命名底层方法似乎也没有影响

值得注意的是,我的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没有。

我一直在捅这么久,有什么想法可能是什么问题?

+0

当你调用/ api/oses/osType时,它没有在控制器中找到控制器或方法? –

+0

对它的调用会导致404找不到消息,但是从Webapi帮助页面看起来知道要解析哪个控制器和方法。 – rheone

+0

在任何mvc路由注册之前调用过MapHttpAttributeRoutes方法吗? –

回答

12

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

按照对Attribute Routing in MVC and Web API微软的CodePlex网站条目设计款规定:

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

因此,内Global.asax(或者注册路线)是适当的调用:

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

不幸的是,这不是正确的答案,并且如果WebApi被配置为这样会导致头痛。 WebApi必须在自己的HttpConfiguration上配置,而不是在GlobalConfiguration上配置。在SO中搜索关于此主题的更多主题。 – MoonStom

+2

@MoonStom:你说的不对。 Globalconfiguration.Configure()将相应的WebApi的HttpConfiguration传入回调。重要的部分是MapHttpAttributeRoutes()必须在调用MapRoute()或MapHttpRoute()之前调用。 –

+0

@MoonStom:这取决于。通过System.Web管道(HttpContext),使用GlobalConfiguration。使用Microsoft.Owin.Host.SystemWeb管道(OwinContext),建议使用新的HttpConfiguration。 –

1

在我来说,这是一个愚蠢的错误,我张贴此所以我后面的人做同样的在量子层面检查其他所有内容之前,错误地阅读了这些内容

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

新年快乐