1. ホーム
  2. c#

Request.Queryの値にStringValuesを使用する理由は何ですか?

2023-08-04 02:14:31

質問

例えば、次のようなURLがあるとします: www.myhost.com/mypage?color=blue

Asp.Net Coreでは、以下のようにしてcolorクエリパラメータの値を取得することになると思います。

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
 }

一つのクエリパラメータが複数の値を持つことは(私の知る限り)あり得ないので、なぜ Request.Query["color"] を返すのでしょうか? StringValues オブジェクトを返しますか?

どのように解決するのですか?

すでに他の方がおっしゃっているように、このタイプは StringValues オブジェクトを使用しています。技術的には複数の値が許可されているからです。一般的には1つの値を設定するだけですが、URIの仕様では値を複数回設定することが禁止されているわけではありません。そして、それをどう処理するかはアプリケーション次第です。

とはいえ StringValues への暗黙の変換があります。 string に暗黙のうちに変換されるので、実際に ToString() を呼び出す必要はなく、単に文字列のように使うことができます。ですから、次のようなことをするのは Request.Query["color"] == "red" のようなことをしたり、文字列を期待するメソッドに渡したりしてもうまくいきます。

さらに悪いことに、クエリパラメータが指定されているかどうかを確認するための値のチェックは、もはや以下のように行うことができません。 Request.Query["color"] == null のようにチェックすることはできませんが、代わりに次のようにチェックする必要があります。 Request.Query["color"].Count == 0

それは半分だけですね。そうです。 StringValues オブジェクトが空であるかどうかを調べるには、その Count プロパティをチェックすることができます。に対してチェックすることもできます。 StringValues.Empty :

Request.Query["color"] == StringValues.Empty

しかし、最初の「問題」は Request.Query[x] 常に は、非NULLの 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);
}