2013-01-02 47 views
0

以前,我有兩個方法,我一個標記與[WebGet]和一個與[WebInvoke(Method = "POST"]瞭解路線,如何創建兩條可以同時爲GET和POST的「相同」路線?

當我做一個GET或POST一個到我指定的,它總是調用正確的方法的URL。

的網址是:

POST: fish-length 
GET: fish-length?start-date={startDate}&pondId={pondId} 

現在,我使用的Web API,我不得不seperately定義我的路線,像這樣:

RouteTable.Routes.MapHttpRoute(
     name: "AddFishLength", 
     routeTemplate: "fish-length", 
     defaults: new 
     { 
      controller = "FishApi", 
      action = "AddFishLength" 
     }); 


    RouteTable.Routes.MapHttpRoute(
     name: "GetFishLength", 
     routeTemplate: "fish-length?start-date={startDate}&pondId={pondId}", 
     defaults: new 
     { 
      controller = "FishApi", 
      action = "GetFishLength" 
     }); 

但是第二條路線行不通,因爲您在routeTemplate中不允許使用?

我可以將URL格式更改爲fish-length/{startDate}/{pondId}之類的東西,但它確實不是一個很好的暴露服務的方式。

有沒有更好的方法來做到這一點?另外,因爲我之前正在做一個POST和GET到相同的URL,我需要確保我的路由方法仍然允許這個。假設上述工作,我仍然不知道它將如何正確路由。

回答

0

不,你不需要定義單獨的路線。所有你需要的是一個單一的路線:

RouteTable.Routes.MapHttpRoute(
    name: "AddFishLength", 
    routeTemplate: "fish-length", 
    defaults: new 
    { 
     controller = "FishApi", 
    } 
); 

然後按照ApiController的行動的REST風格的命名約定:

public class FishApiController: ApiController 
{ 
    // will be called for GET /fish-length 
    public HttpResponseMessage Get() 
    { 
     // of course this action could take a view model 
     // and of course that this view model properties 
     // will automatically be bound from the query string parameters 
    } 

    // will be called for POST /fish-length 
    public HttpResponseMessage Post() 
    { 
     // of course this action could take a view model 
     // and of course that this view model properties 
     // will automatically be bound from the POST body payload 
    } 
} 

所以假設你有一個視圖模型:

public class FishViewModel 
{ 
    public int PondId { get; set; } 
    public DateTime StartDate { get; set; } 
} 

去提前並修改控制器操作以採用此參數:

public class FishApiController: ApiController 
{ 
    // will be called for GET /fish-length 
    public HttpResponseMessage Get(FishViewModel model) 
    { 
    } 

    // will be called for POST /fish-length 
    public HttpResponseMessage Post(FishViewModel model) 
    { 
    } 
} 

對於不同的操作,顯然可能有不同的視圖模型。

+0

我無法弄清楚它是如何映射到該動作。假設我的方法被稱爲'GetFishLength',那麼它如何知道調用它,而不是'GetFishName'?您不在路由信息中指定操作的名稱。 – NibblyPig

0

你不能在路由模板中指定查詢字符串參數 - 但只要你有一個匹配參數名稱的方法,WebApi應該足夠聰明,以便自己弄清楚。

public HttpResponseMessage Get(string id)可能符合要求的{controller}?id=xxx

然而,很難說沒有看到實際的對象,你應該如何去解決你的情況。例如。 WebApi不喜歡Get請求中的複雜類型,並且它僅以特定方式支持發佈數據中的url編碼內容。

至於區分Get和Post很簡單--WebApi知道發送請求時使用了哪種方法,然後它查找以Get/Post或以HttpGet/Post屬性裝飾的方法名稱。

我建議您看看下面的文章 - 他們幫助我理解它是如何工作的:

http://www.west-wind.com/weblog/posts/2012/Aug/16/Mapping-UrlEncoded-POST-Values-in-ASPNET-Web-API

http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx