将数组传递到 ASP.NET Core 路由查询字符串
Posted
技术标签:
【中文标题】将数组传递到 ASP.NET Core 路由查询字符串【英文标题】:Pass Array into ASP.NET Core Route Query String 【发布时间】:2017-09-09 21:44:08 【问题描述】:我想做this,但我也希望能够将数组传递到查询字符串中。我试过这样的事情:
http://www.sitename.com/route?arr[]=this&arr[]=that
http://www.sitename.com/route?arr[]=this&that
http://www.sitename.com/route?arr[0]=this&arr[1]=that
http://www.sitename.com/route?arr0=this&arr1=that
http://www.sitename.com/route?arr=this&arr=that
而我在 C# 代码中的路线如下所示:
[Route("route")]
[HttpGet]
public void DoSomething(string[] values)
// ...
但在所有这些情况下,值在到达 C# 代码时始终为空。我需要什么查询字符串才能传递字符串数组?
【问题讨论】:
不要认为这是可能的 您的参数名称不匹配。更改 arr 或值。 这能回答你的问题吗? Pass an array of integers to ASP.NET Web API? 【参考方案1】:我在你的问题中发现了两个问题:
-
您的查询具有名为
arr
的参数,而您的控制器操作具有 values
。
我不知道为什么,但你必须命名你的参数 (as answered here) 以便 Asp .NET ModelBinder
可以按预期工作。像这样:
public void DoSomething([FromQuery(Name = "values")] string[] values)
完成此操作后,一切都应该按预期工作。
【讨论】:
谢谢,现在已经修好了。【参考方案2】:最后,我只是传入了一个单独的分隔字符串,然后在服务器端使用 string.Split 进行分隔。不是最漂亮的解决方案,但它有效。在有人提出更好的答案之前,这就是我所得到的。我应该重申我使用的是 .NET Core,并且这些查询字符串是特定于框架的。
更新:这种方法的一个(有争议的)好处是您可以一起传递值(例如 arr=value1,value2),而不是重复键(arr=value1&arr=value2)。
【讨论】:
在你的例子中,你有 arr=1&arr=2 但你的变量名是值,所以它肯定应该是 values=1&values=2 名称必须匹配。 想想为你的 api 生成客户端的工具。我更愿意看到一个 id 数组作为客户端的参数,而不是一个不是自我描述的字符串参数。 @MohsenTabareh 这就是我要问的。但是没有人能想出一种对我有用的方法。所以我只需要做便宜的黑客。请参阅 Ilya 答案中的 cmets。请在投票前阅读上下文... 您尝试过我和@abatishchev 提供的解决方案吗? 好吧,我什至不再在那家公司工作了。一年多以前,我问过这个问题。不确定 .NET Core 是否有任何更新解决了这个问题。【参考方案3】:我找到了解决办法。例如,如果您有这样的查询:
http://www.sitename.com/route?arr[]=this&arr[]=that
您必须在参数中定义为[FromQuery(Name = "arr[]")]
。参数名称必须包含方括号。结果我们可以看到:
public void DoSomething([FromQuery(Name = "arr[]")] string[] arr)
【讨论】:
您可以从查询和参数声明中删除 [],例如route?arr=this&arr=that 应该可以工作【参考方案4】:在尝试传入字符串数组时,我在使用 .NET Core 3 时遇到了同样的问题。我通过将查询参数作为临时 json 字符串传递来解决它。然后我使用 Newtonsoft 的 Json 包将字符串反序列化为结果数组
using Newtonsoft.Json;
public IActionResult Get([FromQuery(Name = "array")] string arrayJson)
List<string> array = JsonConvert.DeserializeObject<List<string>>(arrayJson);
【讨论】:
解决方案与接受的答案***.com/a/43474678/52277非常相似,并且user3685285的Split比JsonConvert.DeserializeObject>简单 不得不这样做很烦人,但最后,在使用深层对象时我找不到更简单的解决方案。【参考方案5】:给定:
public ValuesController
public IACtionResult Get([FromUri]string[] arr)
Return Ok(arr.Length);
以下请求将起作用:
GET /api/values/?arr[0]=a&arr[1]=b&arr[2]=c
【讨论】:
【参考方案6】:分隔字符串不是标准。如果您支持 swagger 或其他生成器,还要考虑客户端。
对于那些想知道接收空列表的 .net core 2.1 错误的人,解决方法在这里:https://github.com/aspnet/Mvc/issues/7712#issuecomment-397003420
在 FromQuery 上需要一个名称参数
[FromQuery(Name = "employeeNumbers")] List<string> employeeNumbers
【讨论】:
使用命名参数来使用具有[FromQuery]
属性的复杂类型是一种不好的做法吗?
数组和列表在此上下文中的行为相似。但即使这个答案超出了当前问题的范围,我会说,不,这不是一个坏习惯。你甚至可以拥有像 Person 这样的复杂类型,并通过 FromQuery 提供它的属性:查看此以获取更多信息:docs.microsoft.com/en-us/aspnet/web-api/overview/…
我不知道为什么,但这就像一个魅力,非常感谢!在像你的回答一样命名我的参数之前说我收到 415 HTTP 错误,现在一切都是 200。
这个答案正在解决错误的问题/已过时。如果您将参数名称与传入的值匹配,则不需要名称参数,正如其他答案所指出的那样。
我的查询字符串是 ?arr[]=this&arr[]=that
格式,我可以让它工作的唯一方法是在 FromQuery 名称中包含方括号:[FromQuery(Name = "employeeNumbers[]")] List<string> employeeNumbers
。我不知道这是否有效。【参考方案7】:
在查询字符串中使用参数名称。如果您有操作:
public void DoSomething(string[] values)
然后在查询字符串中使用values
将数组传递给服务器:
?values=this&values=that
【讨论】:
这是我尝试过的事情的清单。它对我不起作用。 @user3685285,我检查了它,它按描述工作。您能否将单个值传递给Foo(string value)
之类的操作?
这就是我知道的方法,但它对我也不起作用。 Unexpected end of Stream, the content may have already been read by another component
@Sinaesthetic 如何将流读取与模型绑定相关联?
@MateuszMigała 是的,它在 1.1 上有效,但在 Core 2.1 上存在错误,如答案 ***.com/a/52222184/5112433 中所述。该错误已在 2.2 中修复。【参考方案8】:
我不得不做与此类似的事情,但不是字符串,而是我使用一个长列表来传递一些 id 进行搜索。使用多选选项,选择的值被发送到方法(通过 get),如下所示:
[HttpGet("[action]")]
public IActionResult Search(List<long> idsSelected)
///do stuff here
我也在类声明之前使用Route("[controller]")
。工作正常,但是项目列表在 url 中被分解为多个参数,如下所示。
http://localhost:5000/Search/idsSelected=1&idsSelected=2
【讨论】:
以上是关于将数组传递到 ASP.NET Core 路由查询字符串的主要内容,如果未能解决你的问题,请参考以下文章
将数组传递给 asp net core web api 操作方法 HttpGet
将中间件附加到 ASP.NET Core Web API 中的特定路由?