2016-11-08 63 views
0

的可變數量我創建了一個GET動作控制器的API:通查詢字符串參數爲單控制器動作

[Route("api/xxxxx/{param1:int}/{param1:int}")] 
public IHttpActionResult Get(int param1, int param2) { 
    // method body... 
} 

的網址,將在以下格式:

/api/xxxxx/1/1?p1=5&p2=hello&p3=20161108 
/api/xxxxx/1/1?p1=active 

查詢字符串參數的數量和名稱將有所不同。

我想將查詢字符串參數傳遞給控制器​​方法,但由於名稱和數字不同,我無法將它們硬編碼到方法簽名中。有沒有辦法做到這一點?我嘗試過撥打var qsParams = ControllerContext.Request.GetQueryNameValuePairs();,但在嘗試使用查詢字符串請求任何網址時,如果給出上述Route屬性,則會收到資源未找到錯誤。

我已經想出了一個替代方案:使用路由值,而不是查詢字符串參數,然後使用捕獲所有{*tags},並把它作爲一個方法參數:

[Route("api/xxxxx/{param1:int}/{param1:int}/{*tags}")] 
public IHttpActionResult Get(int param1, int param2, string tags) { 
    // method body... 
} 

隨着格式

網址
/api/xxxxx/1/1/5/john/20161108 
/api/xxxxx/1/1/active 

這個工作,但我寧願使用查詢字符串,以便能夠使用命名的鍵,而不是依賴於參數的排序(也使用查詢字符串似乎更好的概念匹配,正在做)。

那麼,如何將變量查詢字符串參數傳遞給控制器​​操作?我說「傳遞」了參數,但它們不一定需要作爲方法參數傳遞,只要我可以從方法體中訪問查詢字符串參數,同時獲取帶有查詢字符串的URL以解析爲有問題的行動。

編輯:

值得一提的是,每一個可能的參數集創建多個操作方法是不是一種選擇。

編輯2:

我看到兩個直接的解決方案,如果他們能夠:

  1. 傳遞整個查詢字符串的操作方法作爲單個字符串 參數。然後我可以手動解析查詢字符串。
  2. 能夠在方法體內使用ControllerContext.Request.GetQueryNameValuePairs() ,而不添加相應的參數到 方法簽名。

但是,我還沒有想出如果這兩件事情是可能的,但它似乎可能是一個或兩個都可能。

回答

0

如果你想發送一個實體到你的控制器,你可以通過[FromBody] 得到它認爲一個實體是最簡單的方式來傳遞它。

F.e.

[HttpPost] 
[Route("api/xxxxx/send")] 
public void SendReuqest([FromBody] Entity name) 

希望能理解你的問題。

+0

我沒有任何職位,只得到。此外,這似乎只是將問題轉移到實體。也就是說,現在框架將嘗試將參數映射到實體,但實體必須將參數定義爲屬性。因此,實體必須具有不同的名稱和數量的屬性才能映射到,這與以前相同,但現在嘗試在實體類中尋址。順便說一句,我沒有使用實體框架。 – neizan

0

我發佈了一個文檔替代方案的答案我已經拿出來了。我知道一些(所有?)這些將會是hacky。儘管如此...

ANSWER
使用方法GetQueryNameValuePairs。這是我嘗試的第一件事,但我必須在路由屬性或方法簽名中有不同的東西,因爲我之前收到了「未找到」錯誤。但是,現在,這是完美的。這使得整個問題和答案對我來說基本沒有意義。

實例網址:

/api/xxxxx/1/1?p1=5&p2=john&p3=20161108 

操作:

[Route("api/xxxxx/{param1:int}/{param1:int}")] 
public IHttpActionResult Get(int param1, int param2) { 
    var qsParams = ControllerContext.Request.GetQueryNameValuePairs(); 
    // rest of method body... 
} 

選項1
使用與控制器理解並能夠解析自定義格式的單個查詢字符串參數。

例URL:

/api/xxxxx/1/1?qs=p1~5|p2~john|p3~20161108 

操作:

[Route("api/xxxxx/{param1:int}/{param1:int}")] 
public IHttpActionResult Get(int param1, int param2, string qs) { 
    string[] qsParamsArray = qs.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries); 
    IDictionary<string, string> qsParams = new Dictionary<string, string>(); 
    foreach (string p in qsParamsArray) { 
     string[] kv = p.Split(new string[] { "~" }, StringSplitOptions.None); 
     if (String.IsNullOrWhiteSpace(kv[0])) { 
      return NotFound(); 
     } 
     qsParams.Add(kv[0], kv[1]); 
    } 
    // Use qsParams as desired... 
} 

選項2
把查詢字符串參數中的路由,而不是查詢字符串。必須依賴於參數的排序。

實例網址:

/api/xxxxx/1/1/5/john/20161108 

操作:

[Route("api/xxxxx/{param1:int}/{param1:int}/{*tags}")] 
public IHttpActionResult Get(int param1, int param2, string tags) { 
    // parse the "tags" parameter here... 
    // rest of method body... 
} 

選項3
硬代碼的通用名稱的可選參數的最大數量,具體爲這兩個名字的查詢字符串參數和參數值。

實例網址:

/api/xxxxx/1/1?name1=p1&value1=5&name2=p2&value2=john&name3=p3&value3=20161108 

操作:

[Route("api/xxxxx/{param1:int}/{param1:int}")] 
public IHttpActionResult Get(
    int param1, 
    int param2, 
    string name1 = null, 
    string value1 = null, 
    string name2 = null, 
    string value2 = null, 
    string name3 = null, 
    string value3 = null, 
    string name4 = null, 
    string value4 = null, 
    ..., 
    string nameNMAX = null, 
    string valueNMAX = null 
) { 
    // method body... 
} 
相關問題