2014-04-01 63 views
49

我想辦理下列API呼叫的POST:可選參數屬性路由

/v1/location/deviceid/appid

其它參數從後車身的到來。

這一切都適合我。現在我wnat允許「設備ID」和/或「的appid」和/或BodyData爲空致以代碼:

/v1/location/deviceid 
/v1/location/appid 
/v1/location/ 

這3個網址應該通過相同的途徑迴應。

我的第一種方法(BodyData要求):

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")] 
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody] location_fromuser BodyData) 
{ 
    return repository.AddNewLocation(deviceid, appid, BodyData); 
} 

這不起作用,並返回一個編譯錯誤:

"optional Parameters must be at the end"

下一個嘗試:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")] 
public location_fromuser Post([FromBody] location_fromuser BodyData, string deviceid = null, string appid = null) 

現在我的功能AddNewLocation ()始終得到一個BodyData=null - 即使呼叫發送正文。

最後,我將所有3參數可選:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")] 
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody location_fromuser BodyData = null) 

鴕鳥政策工作:

Optional parameter BodyData is not supported by FormatterParameterBinding .

爲什麼我要使用可選參數的解決方案?我的控制器通過POST處理「添加新位置」。

我想發送錯誤的數據我自己的例外或錯誤消息。即使呼叫有缺失值。在這種情況下,我希望能夠決定拋出異常或通過我的代碼設置默認值。

回答

105

對於像/v1/location/1234傳入的請求,你可以想像這將是困難的,如果對應於「1234」段的值與appid而不是deviceid的Web API自動找出。

我想你應該改變你的路線模板,如 [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]然後解析deiveOrAppid找出id的類型。

此外,您需要使路線模板本身中的線段可選,否則將根據需要對線段進行考慮。在這種情況下請注意?字符。 例如: [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]

+17

路由模板內部的'?'是我正在尋找的內容。 +1 –

+4

我不會說「deviceOrAppId」是最好的設計選擇。我認爲API應該始終明確地知道它將如何可能收到。 –

+3

僅供參考 - 當我們使用'?'字符在動作uri中將參數標記爲可選參數時,我們必須爲方法簽名中的參數提供默認值,例如MyMethod(string name =「someDefaultValue」,int?Id = null)。 – RBT

29

另一個信息:如果你想使用路由約束,假設你要強制該參數有INT數據類型,那麼你需要使用這個語法:

[Route("v1/location/**{deviceOrAppid:int?}**", Name = "AddNewLocation")] 

字符放在總是最後}字符

前欲瞭解更多信息,請參閱:Optional URI Parameters and Default Values

4

轉換我的評論到答案補充@Kiran查拉的答案,因爲它似乎在audiences-

有幫助當我們使用?字符在動作uri中將參數標記爲可選參數時,我們必須爲方法簽名中的參數提供默認值,如下所示:

MyMethod(string name = "someDefaultValue", int? Id = null)

+0

我即將對此發表評論。 – Jnr