2014-02-06 148 views
2

此問題可能已被答覆了上百次,但我找不到合適的資源。在WebApi項目(VS提供的默認項目)中,我有如下的ValuesController。具有不同參數名稱的Web api路由方法

public string Get(int id) 
    { 
     return "value"; 
    } 

    [HttpGet] 
    public string FindByName(string name) 
    { 
     return name; 
    } 

    [HttpGet] 
    public string FindById(int id) 
    { 
     return id.ToString(); 
    } 

在WebApiConfig.cs中,我有以下路由映射。

config.Routes.MapHttpRoute(
       name: "actionApiById", 
       routeTemplate: "api/{controller}/{action}/{Id}", 
       defaults: new { action = "FindById", Id = RouteParameter.Optional } 
      ); 


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

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

現在只有FindById()動作正在工作,當我嘗試在瀏覽器中。爲什麼其餘的api調用返回「沒有找到與請求匹配的HTTP資源

如何獲得所有三種方法的工作?而不使用AttributeRouting。我缺乏web api的基本概念嗎? (我認爲是)

+0

你的意思是你不能調用「Get」方法?如果是這樣,請分享您從客戶端調用方法的方式? – Thanigainathan

回答

1

您的actionApiById路由也匹配actionApi路由,因爲您的id是整數嘗試使用像這樣的約束。

config.Routes.MapHttpRoute(
       name: "actionApiById", 
       routeTemplate: "api/{controller}/{action}/{Id}", 
       defaults: new { action = "FindById", Id = RouteParameter.Optional } 
       constraints: new {Id = @"\d+" } 
      ); 
+0

我只是想通了...... – JenonD

2

一般而言,您不希望像您的樣本建議一樣採取行動。隨着您的應用程序的增長,這將很快失去控制。

也可以考慮的方式,將尋找建立您的網址空間只是問題的REST

這樣的方法將是GetByIdGetByName,然後傳遞參數的查詢字符串匹配正確的行動(順便說一句不知道的在你的情況下,差異在GetByIdFindById之間,如果他們沒有什麼不同,就考慮只保留其中一個)。

您可以用默認路由堅持,而且要求將是這樣的:

/api/controller/345 or /api/controller?name=UserName or /api/controller?SearchId=345 (assuming search was indeed a different behavior) 

隨後的方法簽名:

Get(int id) 
{ 
} 

[HttpGet] 
FindByName(string name) 
{ 
} 

[HttpGet] 
FindById(int searchId) 
{ 
} 
4

大家都知道REST是基於資源,這個標識資源與URL一起使用,以便在REST服務中允許使用不多於一個具有相同參數的方法,但是在MVC 5 Web Api方法級別路由中有解決方法。

這裏是你可以做的是,例如:

[HttpGet] 
[Route("api/search/FindByName/{name}")] 
FindByName(string name) 
{ 
} 

[HttpGet] 
[Route("api/search/FindById/{name}")] 
FindById(int searchId) 

注:「搜索」是控制器的名字。

請讓我們知道是否需要更多的澄清。

+0

是的,我喜歡這個解決方案,是我實施的,但我不知道這是否是好的做法? –

相關問題