Request.Queryの値にStringValuesを使用する理由は何ですか?
質問
例えば、次のような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);
}
関連
-
[解決済み] DBNullから他の型にオブジェクトをキャストすることができない
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] EqualsメソッドがオーバーライドされたときにGetHashCodeをオーバーライドすることが重要な理由は何ですか?
-
[解決済み] C#でHashtableよりDictionaryが好まれる理由とは?
-
[解決済み] URLのPath.Combineは?
-
[解決済み】C#のyieldキーワードは何に使われるのか?
-
[解決済み】汎用辞書の大文字・小文字を区別しないアクセス方法
-
[解決済み】.NETで構造体のデフォルトコンストラクタを定義できないのはなぜですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】「未割り当てのローカル変数を使用」とはどういう意味ですか?
-
[解決済み】指定されたキャストが有効でない?
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み】パディングが無効で、削除できない?
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】C#のequal to演算子でtextとvarcharのデータ型は互換性がない
-
[解決済み】プロセスが実行されているかどうかを知るには?
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。
-
[解決済み】スレッド終了またはアプリケーションの要求により、I/O操作が中断されました。