C# 为什么StringValues用于Request.Query值?

C# 为什么StringValues用于Request.Query值?,c#,asp.net-core,C#,Asp.net Core,假设我有一个类似这样的url:www.myhost.com/mypage?color=blue 在Asp.Net Core中,我希望通过执行以下操作获得颜色查询参数值: string color=Request.Query[“color”] 但是,Request.Query[“color”]返回类型为StringValues的值,而不是string。为什么呢 显然,StringValues类型可以保存一个字符串数组,并支持隐式转换为string[],这很酷,但是为什么查询参数值需要这样做呢 必须

假设我有一个类似这样的url:www.myhost.com/mypage?color=blue

在Asp.Net Core中,我希望通过执行以下操作获得颜色查询参数值:

string color=Request.Query[“color”]

但是,
Request.Query[“color”]
返回类型为
StringValues
的值,而不是
string
。为什么呢

显然,
StringValues
类型可以保存一个字符串数组,并支持隐式转换为
string[]
,这很酷,但是为什么查询参数值需要这样做呢

必须获得这样的值似乎很奇怪:

string color=Request.Query[“color”].ToString()

更糟糕的是,检查一个值以查看是否指定了查询参数不能再这样做了

  if(Request.Query["color"] == null) { 
      //param was not specified
  }
但必须像这样进行检查

 if(Request.Query["color"].Count == 0) { 
      //param was not specified
 }

既然一个查询参数不能有多个值(据我所知),为什么
请求.query[“color”]
返回一个
StringValues
对象而不是字符串?

,因为您的查询可以如下所示:

www.myhost.com/mypage?颜色=蓝色&颜色=红色&颜色=黄色

然后从一个
请求中获取所有
color
值。查询[“color”]
参数
请求。查询[“color”]
返回
StringValues
,因为可以传递
字符串
值的集合。所以,我建议您将其作为动作参数处理,即模型绑定

public ActionResult SaveColor([FromUri] string[] color);

正如其他人已经提到的,该类型是一个
StringValues
对象,因为技术上允许多个值。虽然通常的做法是只设置一个值,但URI规范不允许多次设置值。由应用程序决定如何处理

也就是说,
StringValues
有一个到
string
的隐式转换,因此实际上不需要对其调用
ToString()
,只需将其当作字符串使用即可。因此,执行诸如
Request.Query[“color”]=“red”
之类的操作,或者将其传递给需要字符串的方法就可以了

更糟糕的是,检查值以查看是否指定了查询参数不能再像so
Request那样进行。查询[“color”]==null
,而必须像so
Request那样进行检查。查询[“color”]。计数==0

那只对了一半。是,为了检查
StringValues
对象是否为空,可以检查其
Count
属性。您还可以对照
StringValues进行检查。空的

Request.Query["color"] == StringValues.Empty
但是,最初的“问题”是,
Request.Query[x]
始终返回一个非空的
StringValues
对象(因此可以安全地检查任何值)。如果要检查查询参数中是否存在键,应使用
ContainsKey

if (Request.Query.ContainsKey("color"))
{
    // only now actually retrieve the value
    string colorValue = Request.Query["color"];
}
或者,使用
TryGetValue

if (Request.Query.TryGetValue("color", out var colorValue))
{
    DoSomething(colorValue);
}

尽管如此,在大多数情况下访问
Request.Query
并不是真正必要的。您只需使用,它将自动为您提供所需的查询参数,只需将它们包含在操作的签名中:

public ActionResult MyAction(string color)
{
    DoSomething(color);
}

只是为好奇的灵魂发帖,可能与问题无关。只是一个警告

我发现自己也遇到了类似的问题。这种类型还有一些其他问题

  • 如果查询参数没有值。例如:
    /products?pageNo=1&pageSize=

    您将发现自己在
    pageSize
    参数中引发异常,如
    Count
    StringValues
    上的属性将为您提供值1,但底层的
    \u值
    (空) 字符串)和
    \u值
    null
    。注意-当您试图转换或 访问IQueryCollection中的值)

  • 使用
    TryGetValue
    将安全地将值从
    StringValues
    中取出,但如果值为空 (就像上面的
    pageSize
    参数一样),您很难找出原因 您不能将
    StringValues
    转换为simple
    String
    吗,或者为什么不能与
    null
    进行比较 对其进行进一步的操作,如验证等

  • 要对
    StringValues
    type执行任何检查,请使用该类型提供的方法


  • 要检查是否为null或空,请使用-
    StringValues.IsNullOrEmpty(StringValues值)

    您希望www.myhost.com/mypage的值是什么?color=blue&color=red&color=green@podiluska我不知道多次指定参数是有效的。如果我这样做了,我会希望只收到最后一个,即您的示例中的绿色。不要使用
    请求。查询
    ,而是使用它。@RonC我很确定这就是查询字符串的工作方式。但目前在querystring上提供集合的“智慧”是重复这个关键。你和我是否同意这一点无关紧要:)你可以使用
    var color=Request.Query[“color”];if(StringValues.IsNullOrEmpty(color)){//do something}谢谢,我不知道在查询字符串中多次指定同一查询参数是有效的。考虑到它在web上的使用频率(以前从未见过它,并且自1995年以来一直在进行web开发),我希望它不被允许,因为它使代码对于很少使用的edge案例来说不那么优雅。但现在我明白了为什么引入“StringValues”。有趣的是,
    StringValues
    的概念是在Asp.Net核心之前引入的,Asp.Net的早期版本返回字符串。我想知道为什么.Net核心中的QueryHelpers.AddQueryString是:QueryHelpers.AddQueryString(string uri,IDictionary queryString)如果url是
    www.myhost.com/mypage?colo,那么这段代码会返回什么