【问题标题】:How do I reproduce the [FromUri] behavior for complex parameters in .NET Core 2.1如何在 .NET Core 2.1 中重现复杂参数的 [FromUri] 行为
【发布时间】:2018-12-27 15:36:58
【问题描述】:

我目前正在创建一个新的 API,但我需要通过 URL 接收复杂的参数。我不能轻易更改这些参数而不冒其他系统出错的风险。

我使用的是 .Net Core 2.1,由于 [FromUri] 不存在,我不得不使用 [FromQuery]。问题是它不会填充复杂的参数。我知道这不是 .NET Core 的基本功能,但四处搜索我找到了解决方案,但似乎没有一个有效。我尝试了一个干净的项目并遇到了同样的问题。

示例网址:https://localhost:44337/api/values?simple=true&foo[0][value]=1&foo[0][name]=bar&foo[1][value]=2&foo[1][name]=ultra%20bar

使用 Visual Studio 2017 中的基本核心 API 模板,我只更改了控制器。

public class FooParameter
{
    public string value { get; set; }
    public string name { get; set; }
}
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get([FromQuery]bool simple, [FromQuery]FooParameter[] foos)
{
    return new string[] { "value1", "value2" };
}

结果是:

simple = True
foos = Length 0 Array of FooParameter

我试过了

  • 使用 Microsoft.AspNetCore.Mvc.WebApiCompatShim:无
  • 使用自定义 ModelBinder :似乎认为 foo[0][value] 是参数的整个键
  • 使用动态或对象作为类型:空对象
  • 减少到一级 "&foo[value]=1&foo[name]=bar" 代替(用于测试):包含 null,null

我可以自己用 Request.Query 解析所有内容,但它也认为“foo[0][value]”是参数键,我得到了一个巨大的可能性列表。

我很确定我错过了一些完全明显的东西,但我找不到任何东西。我唯一的限制是我不能触摸查询字符串格式。

【问题讨论】:

  • 嗨,我遇到了同样的问题,当我想发送一个列表或值表作为 url 参数时。我认为它总是会产生错误。我建议将链接从这个:“localhost:44337/api/…”翻译成这个:“localhost:44337/api/…”。控制器方法可以接受此链接作为表“FooParamter[] foos”。
  • @mehdizahrane 我是这么认为的,但就像我说的那样,我不能在不失去理智的情况下更改 URL。长话短说,我在这里得到了一些东西,它们通过自动脚本从 Fortran 之类的东西转换为 C++,然后包装在托管 C++ 中,然后包装在 C# 中,所以只要看看这些代码就足以让你大哭一场,为甜蜜的解脱而哭泣死亡。
  • 使用自定义 ModelBinder :似乎认为 foo[0][value] 是参数的整个键这是正确的行为。 HTTP/HTML 不知道对象、数组等,所以foo[0][value]。将这些解释为键或对象结构完全取决于服务器应用程序。
  • 例如:param=value&amp;param=value2&amp;param=value3。这将被解释为具有 3 个不同值的 3 个参数。 HOW 服务器/框架如何解释这完全取决于框架的实现。 ASP.NET Core 会将其绑定到 string[] 数组。另一方面,PHP 会将其视为单个参数,除非您传递发送 param[]=value&amp;param[]=value2&amp;param[]=value3param[0]=value&amp;param[1]=value2&amp;param[3]=value3,否则只会采用 3 个值中的一个。对于 HTML/HTTP,它只有 3 个键和 3 个值
  • @Tseng 因此,如果我理解正确,我的选择是:1)制作一个代理,以支持的格式重新格式化查询并将其发送到 API 2)诅咒 .Net 核心并迁移到框架 3 ) 咬紧牙关,编写我自己的解析器来模拟正确的解释,就像 [FromUri] 所做的那样。

标签: c# asp.net-core asp.net-core-2.0


【解决方案1】:

我找到了必须转换参数的方式,以便正确加载 HTML 数组。它不是完全动态的,但可以满足我的需求。

您需要使用 FromQuery 上的 Name 属性才能获取对象。

public class FooBar
{
    [FromQuery(Name = "[bar]")]
    public string bar { get; set; }
    [FromQuery(Name = "[id]")]
    public int id { get; set; }
}
// GET api/values
[HttpGet]
public ActionResult<FooBar> Get([FromQuery(Name = "foo")]FooBar[] foo)
{
    return foo;
}

这需要 ?foo[0][bar]=val&foo[0][id]=1&foo[1][bar]=val2&foo[1][id]=2 并返回 [{"bar":"val ","id":1},{"bar":"val2","id":2}]

您可以保留[ApiController],无需制作自定义ModelBinder。

【讨论】:

  • 为什么要覆盖默认名称,应该可以绑定到 Foo[0].Bar
  • @johnny5 你的意思是像 Get([FromQuery]FooBar[] foo) ?它不起作用,我得到一个空数组。
  • 好吧,你是对的。没有尝试 Get([FromQuery(Name = "foo")]FooBar[] foo)。我会更正答案。
  • 我的意思是你的查询字符串
  • @johnny5 我无法更改查询字符串格式。我坚持使用香草 HTML 表单的方式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多