私はこれができることを知っています
var nv = HttpUtility.ParseQueryString(req.RawUrl);
しかし、これをURLに戻す方法はありますか?
var newUrl = HttpUtility.Something("/page", nv);
私はこれができることを知っています
var nv = HttpUtility.ParseQueryString(req.RawUrl);
しかし、これをURLに戻す方法はありますか?
var newUrl = HttpUtility.Something("/page", nv);
を呼び出すだけToString()
でNameValueCollection
、名前と値のペアがname1=value1&name2=value2
クエリ文字列対応の形式で返されます。型は実際にはこれをサポートしておらず、これを示唆するのは誤解を招くことに注意してください。ただしNameValueCollection
、以下で説明するように、実際に返される内部型により、動作はここで機能します。
メソッドが実際には通常のオブジェクトではなくHttpUtility.ParseQueryString
内部オブジェクトを返すことを指摘してくれた@mjwillsに感謝します(ドキュメントで指定されているにもかかわらず)。は、使用時にクエリ文字列を自動的にエンコードするため、コレクションをループしてメソッドを使用するルーチンを記述する必要はありません。目的の結果はすでに返されています。HttpValueCollection
NameValueCollection
NameValueCollection
HttpValueCollection
ToString()
UrlEncode
結果が手元にあれば、それを URL に追加してリダイレクトできます。
var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString());
string url = Request.Url.AbsolutePath + "?" + nameValues.ToString();
Response.Redirect(url);
現在、a を使用する唯一の方法HttpValueCollection
は、ParseQueryString
上記の方法を使用することです (もちろん、リフレクションは別です)。このクラスの公開を要求する Connect の問題は「修正されません」というステータスでクローズされているため、これは変更されないようです。
余談ですが、Add
、Set
、およびRemove
メソッドを呼び出してnameValues
、クエリ文字列アイテムを追加する前に変更できます。興味がある場合は、別の質問に対する私の回答を参照してください。
いくつかのループを使用する拡張メソッドを作成します。読み取り可能 (linq なし) であり、System.Web.HttpUtility を必要とせず、重複キーをサポートするため、私はこのソリューションを好みます。
public static string ToQueryString(this NameValueCollection nvc)
{
if (nvc == null) return string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string key in nvc.Keys)
{
if (string.IsNullOrWhiteSpace(key)) continue;
string[] values = nvc.GetValues(key);
if (values == null) continue;
foreach (string value in values)
{
sb.Append(sb.Length == 0 ? "?" : "&");
sb.AppendFormat("{0}={1}", Uri.EscapeDataString(key), Uri.EscapeDataString(value));
}
}
return sb.ToString();
}
var queryParams = new NameValueCollection()
{
{ "order_id", "0000" },
{ "item_id", "1111" },
{ "item_id", "2222" },
{ null, "skip entry with null key" },
{ "needs escaping", "special chars ? = &" },
{ "skip entry with null value", null }
};
Console.WriteLine(queryParams.ToQueryString());
?order_id=0000&item_id=1111&item_id=2222&needs%20escaping=special%20chars%20%3F%20%3D%20%26
は同じキーに対して複数の値を持つことができるためNameValueCollection
、クエリ文字列の形式に関心がある場合 (「配列表記」ではなくコンマ区切りの値として返されるため)、次のことを考慮することができます。
var nvc = new NameValueCollection();
nvc.Add("key1", "val1");
nvc.Add("key2", "val2");
nvc.Add("empty", null);
nvc.Add("key2", "val2b");
key1=val1&key2[]=val2&empty&key2[]=val2b
ではなく: に変換しますkey1=val1&key2=val2,val2b&empty
。
string qs = string.Join("&",
// "loop" the keys
nvc.AllKeys.SelectMany(k => {
// "loop" the values
var values = nvc.GetValues(k);
if(values == null) return new[]{ k };
return nvc.GetValues(k).Select( (v,i) =>
// 'gracefully' handle formatting
// when there's 1 or more values
string.Format(
values.Length > 1
// pick your array format: k[i]=v or k[]=v, etc
? "{0}[]={1}"
: "{0}={1}"
, k, HttpUtility.UrlEncode(v), i)
);
})
);
または、Linqがあまり好きでない場合...
string qs = nvc.ToQueryString(); // using...
public static class UrlExtensions {
public static string ToQueryString(this NameValueCollection nvc) {
return string.Join("&", nvc.GetUrlList());
}
public static IEnumerable<string> GetUrlList(this NameValueCollection nvc) {
foreach(var k in nvc.AllKeys) {
var values = nvc.GetValues(k);
if(values == null) { yield return k; continue; }
for(int i = 0; i < values.Length; i++) {
yield return
// 'gracefully' handle formatting
// when there's 1 or more values
string.Format(
values.Length > 1
// pick your array format: k[i]=v or k[]=v, etc
? "{0}[]={1}"
: "{0}={1}"
, k, HttpUtility.UrlEncode(values[i]), i);
}
}
}
}
すでにコメントで指摘されているように、この回答を除いて、他の回答のほとんどは、文字通りの質問ではなく、シナリオ ( Request.QueryString
is an HttpValueCollection
、「not」 a ) に対処しています。NameValueCollection
更新:コメントからの null 値の問題に対処しました。
簡単な答えは、 で使用.ToString()
し、NameValueCollection
それを元の URL と組み合わせることです。
ただし、いくつかの点を指摘したいと思います。
HttpUtility.ParseQueryString
では使用できませんRequest.RawUrl
。このParseQueryString()
メソッドは次のような値を探しています: ?var=value&var2=value2
.
パラメータを取得したい場合はNameValueCollection
、 を使用してください。QueryString
Request.QueryString()
var nv = Request.QueryString;
URL を再構築するには、nv.ToString() を使用するだけです。
string url = String.Format("{0}?{1}", Request.Path, nv.ToString());
Request
オブジェクトを使用する代わりに URL 文字列を解析しようとしている場合はUri
、HttpUtility.ParseQueryString
メソッドを使用します。
Uri uri = new Uri("<THE URL>");
var nv = HttpUtility.ParseQueryString(uri.Query);
string url = String.Format("{0}?{1}", uri.AbsolutePath, nv.ToString());
私は常に UriBuilder を使用して、クエリ文字列を含む URL を有効で適切にエンコードされた URL に変換します。
var url = "http://my-link.com?foo=bar";
var uriBuilder = new UriBuilder(url);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
query.Add("yep", "foo&bar");
uriBuilder.Query = query.ToString();
var result = uriBuilder.ToString();
// http://my-link.com:80/?foo=bar&yep=foo%26bar
@Atchitutchuk が示唆したように、ASP.NET Core で QueryHelpers.AddQueryString を使用できます。
public string FormatParameters(NameValueCollection parameters)
{
var queryString = "";
foreach (var key in parameters.AllKeys)
{
foreach (var value in parameters.GetValues(key))
{
queryString = QueryHelpers.AddQueryString(queryString, key, value);
}
};
return queryString.TrimStart('?');
}
You can use.
var ur = new Uri("/page",UriKind.Relative);
if this nv is of type string you can append to the uri first parameter. Like
var ur2 = new Uri("/page?"+nv.ToString(),UriKind.Relative);