2016-07-07 146 views
1

我使用WebAPI 2.2,基於屬性的路由,我似乎無法弄清楚爲什麼查詢字符串不工作或如何啓用它們。我已經閱讀過其他關於這個問題的SO問題,但他們並不完全適用於我。WebAPI 2.2,基於屬性的路由和查詢字符串

這裏是一個非常簡單的APIController:

[Route("api/HelloMessage")] 
public async Task<IHttpActionResult> Get() 
{ 
    var result = await Task.FromResult(new string[] { "Hello", "World" }).ConfigureAwait(false); 
    return Ok(result); 
} 

[Route("api/HelloMessage/{id}")] 
public async Task<IHttpActionResult> Get(int id) 
{ 
    var result = await Task.FromResult($"Hello {id}").ConfigureAwait(false); 
    return Ok(result); 
} 

(也去WebApiConfig.cs,並註釋掉與MapHttpRoute創建的默認路由)

如果我http://localhost/api/HelloMessage/1打它,它效果很好。

但是,如果我用http://localhost/api/HelloMessage?id=1命中它,它會綁定到無參數版本。我哪裏錯了?

一個奇怪的事情:

如果我重新啓用MapHttpRoute代碼,然後路由作品(所以ID = 1級的路由參數化的方法?)。

我很想知道爲什麼這不適用於基於屬性的路由。這是一個錯誤,還是我做錯了?

這裏的MapHttpRoute代碼,這將使它的工作:

config.Routes.MapHttpRoute(
     name: "DefaultApi", 
     routeTemplate: "api/{controller}/{id}", 
     defaults: new { id = RouteParameter.Optional } 
    ); 

回答

1

這是由設計。默認的基於約定的路由將映射像api/{controller}/{id}這樣的路由到您的無參數動作,因爲{id}是可選的,如defaults: new { id = RouteParameter.Optional }所述。

使用屬性路由,但您在路由過程中擁有更多的控制權和靈活性。

例如,在屬性路由就可以使id可選這樣

[Route("api/HelloMessage/{id?}")] 
public async Task<IHttpActionResult> Get(int id) {...} 

但是,這將導致與第一條路線有衝突,因爲現在它們都匹配api/HelloMessage

如果你想要http://localhost/api/HelloMessage?id=1通過從uri中檢索id來工作,那麼你需要首先刪除沒有參數的動作,或者改變它的路徑以使其不同,並使其他動作的id可選。

框架工作將匹配URI中的?id=1與參數並將值傳遞給參數。

+0

謝謝恩科西。我發現使用HttpMapRoute()獲得的行爲與使用基於屬性的路由獲得的行爲如此不同是非常奇怪的。我想知道他們爲什麼使他們的功能如此不同。 – JMarsch

+0

我相信我讀過的地方有不同的團隊在MVC和Web Api框架上工作。他們可能會共享類似的功能,但是在不同的環境下它的開發方式不同它最終在vNext版本中合併爲一個通用版本,最終成爲asp dot net核心。 – Nkosi