我正在创建一个具有一个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
属性,我会收到资源未找到错误。
我提出了一个替代方案:使用路由值而不是查询字符串参数,然后使用catch-all {*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
这很有效,但是我宁愿使用查询字符串来使用命名键而不是依赖于参数的排序(同样,使用查询字符串似乎更符合我的概念匹配&#39我正在做。)
那么,如何将变量查询字符串参数传递给控制器操作?我说"传递"参数,但它们不一定需要作为方法参数传递,只要我可以从方法体访问查询字符串参数,同时获取带有查询字符串的URL以解析相关操作
编辑:
值得一提的是,为每个可能的参数集创建多个动作方法都不是一种选择。
编辑2:
如果他们有可能,我会看到两个直接的解决方案:
ControllerContext.Request.GetQueryNameValuePairs()
在方法体内,而不是添加相应的参数
方法签名。但是,我还没弄清楚这两件事是否可能,虽然看起来很可能是其中之一。
答案 0 :(得分:0)
如果您想将实体发送到您的控制器,您可以通过[FromBody]获取它 认为实体是传递它的最简单方法。
F.e。
[HttpPost]
[Route("api/xxxxx/send")]
public void SendReuqest([FromBody] Entity name)
希望能够正确理解你的问题。
答案 1 :(得分: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
使用单个查询字符串参数和控制器理解并能够解析的自定义格式。
示例网址:
/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...
}