2013-08-29 32 views
12

我已被分配爲爲應用程序開發WebAPI控制器(以前我從未使用過的東西)。一切都很順利,有一些基本的請求,如GetAllUsers(int id)僅僅用於測試的原因 - 配置本身很好。測試以對象作爲參數的GET請求(Asp.NET WebApi控制器)

現在是這個問題。我有一個方法 GetAllItems(Carrier carrier)其中載波是一個有許多不同參數的類。由於我們在數據庫中已經有幾個Carrier實例用於測試目的,我試過的是查詢數據庫,根據ID(GUID)屬性選擇Carrier的實例,但沒有結果。

當輸入參數是一個對象而不是一個單獨的值(例如int ID)時,是否有方法來手動測試GET方法,或者使用某種測試方法或測試輸入參數?

編輯:謝謝大家的反饋,我的問題的解決方案實際上比我預期的更容易修復。我非常想愛上你們所有人,但不幸的是,我的名聲太低了(我不熟悉stackoverflow),所以我不得不在不久的將來回到過去。歡呼聲:)

+1

對象是否來自參數non-null?這可能是序列化的問題。該對象來自哪裏,它的屬性如何在GET請求中發送? – Slavo

+0

請提供有關Carrier類別的更多信息以及GetAllItems的預期結果。它看起來應該返回某種載體細節記錄... –

+0

是的,它可以做到,但你可能應該閱讀以下帖子,然後再決定這樣做:http://stackoverflow.com/questions/11091160/rest- api-get-request-with-body和http://stackoverflow.com/questions/978061/http-get-with-request-body –

回答

19

據我瞭解您的問題,您希望能夠直接在URL中傳遞Carrier的屬性,而不是在請求主體中。

例如:

[GET] http://localhost/entities?id=000000000000000 

您控制器的方法是這樣的一個

GetAllItems(Carrier carrier) 

載體的ID(GUID)屬性:

class Carrier { 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
} 

開利公司是長期複雜對象WebApi模型綁定。爲模型綁定

默認行爲是:

默認的Web API使用下列規則綁定參數: 如果參數是一個「簡單」的類型,網頁API試圖獲得的價值來自URI。簡單類型包括.NET原始類型(int,bool,double等),加上TimeSpan,DateTime,Guid,decimal和string,以及任何類型的轉換器都可以從字符串轉換。 (稍後關於類型轉換器的更多信息。) 對於複雜類型,Web API嘗試使用媒體類型格式化程序從消息正文中讀取值。

見:http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

期待一個模型URL中的複雜對象綁定不是的WebAPI默認行爲。

如果你想讓你的控制器方法模型綁定一個複雜的對象從URL你必須告訴它。

GetAllItems([FromUri] Carrier carrier) 

隨着FromUri約束力的指標,可以使用複雜的模型從URL

現在,你甚至可以在URL中添加更多的屬性映射結合:

[GET] http://localhost/entities?id=000000000000000&name=ABC 

GetAllItems將收到載體對象填充: carrier.Id = 0000-00000000000-000; carrier.Name =「ABC」

+0

我可以有一個像Get(int id)這樣的方法,另一個像Get [[FromUri] Carrier c)'...,太多匹配'get'錯誤'? – eRaisedToX

3

這裏有一個路由問題以及一些誤解。

爲的WebAPI的默認路由是:

routes.MapHttpRoute(
      name: "Default", 
      routeTemplate: "{controller}/{action}/{id}", 
      defaults: new { id = RouteParameter.Optional } 
     ); 

這與某些約定一起:

  • 的getX地圖GET方法。
  • InsertX映射POST方法。
  • UpdateX映射PUT方法。
  • DeleteX映射DELETE方法。

當你的命名約定是不符合WepApi公約對齊,那麼你就需要指定方法,動作名稱等

同樣的,你的路線發生。如果你沒有定義其他路由,那麼只有遵循約定和默認路由的動作纔會被限制。

例如:

public IEnumerable<Carrier> GetAll(){ 
    //this will get called when using the route: /api/carriers/ 
} 

public IEnumerable<Carrier> Get(string id){ 
    //this will be called when using the route: /api/carriers/1 
    //where 1 is the carrier id 
} 

將在CarrierController工作,因爲它們都與公約和路線一致。現在

,如果需要返回所有項目的一個載體的方法,你將需要這個方法:

[ActionName("getItems")] 
public IEnumerable<Item> GetAllItems(string id){ 
    //where id is the carrierid  
    var carrierId = id; 
    //because you are specifying the ActionName to getItems this will match the following route: 
    // /api/carriers/getItems/1 
} 

另一種選擇是創建上述ItemsController,並補充說,返回的項目列表的作用基於carrierId,這在概念上可能更好,但路由原則是相同的。

+0

儘管這並沒有完全回答OP的問題,但它寫得很好,內容翔實且簡潔。 – gitsitgo

+0

@gitsitgo,同意了,給了很多信息.. +1 – eRaisedToX