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這個詞結尾。

新年快樂