15

私は次のNameValueCollectionように初期化されたユーザーコントロールを持っています:

private NameValueCollection _nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString());

これを呼び出すとToString()、更新された URL に使用できる適切なクエリ文字列が生成されます。

ただし、NameValueCollectionコンストラクターを介してコピーすると、次のようになります。

var nameValues = new NameValueCollection(_nameValues);

次に、URL を作成してみます。

var newUrl = String.Concat(_rootPath + "?" + nameValues.ToString());

次のような URL を出力します。

" http://www.domain.com?System.Collections.Specialized.NameValueCollection "

メソッドが目的の結果を出力するNameValueCollectionようにa をコピーするにはどうすればよいですか?ToString()

4

3 に答える 3

22

問題は、コードに 2 つの実際の型があることです。1 つ目はSystem.Web.HttpValueCollection、ToString メソッドをオーバーライドして期待どおりの結果を取得するもので、2 つ目はSystem.Collection.Specialized.NameValueCollectionToString をオーバーライドしないものです。本当に使用する必要がある場合にできることはSystem.Collection.Specialized.NameValueCollection、拡張メソッドを作成することです。

 public static string ToQueryString(this NameValueCollection collection)
 {
        var array = (from key in collection.AllKeys
                     from value in collection.GetValues(key)
                     select string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value))).ToArray();
        return "?" + string.Join("&", array);
    }

そしてそれを使用します:

var newUrl = String.Concat(_rootPath,nameValues.ToQueryString());
于 2013-11-01T09:43:27.743 に答える
3

NameValueCollection文字列の書式設定を提供するわけではありません。System.Web.HttpValueCollectionその機能は、によって返される内部クラスにありHttpUtility.ParseQueryStringます。

したがって、組み込み機能を使用してこの動作を実現することはできません。最善の策は、値を URL 形式にフォーマットする拡張メソッドを作成することです。

クラスのメソッドは次のHttpValueCollectionとおりです。いくつかの変更を加えて使用できる場合があります。

// System.Web.HttpValueCollection
internal virtual string ToString(bool urlencoded, IDictionary excludeKeys)
{
    int count = this.Count;
    if (count == 0)
    {
        return string.Empty;
    }
    StringBuilder stringBuilder = new StringBuilder();
    bool flag = excludeKeys != null && excludeKeys["__VIEWSTATE"] != null;
    for (int i = 0; i < count; i++)
    {
        string text = this.GetKey(i);
        if ((!flag || text == null || !text.StartsWith("__VIEWSTATE", StringComparison.Ordinal)) && (excludeKeys == null || text == null || excludeKeys[text] == null))
        {
            if (urlencoded)
            {
                text = HttpValueCollection.UrlEncodeForToString(text);
            }
            string value = (text != null) ? (text + "=") : string.Empty;
            string[] values = this.GetValues(i);
            if (stringBuilder.Length > 0)
            {
                stringBuilder.Append('&');
            }
            if (values == null || values.Length == 0)
            {
                stringBuilder.Append(value);
            }
            else
            {
                if (values.Length == 1)
                {
                    stringBuilder.Append(value);
                    string text2 = values[0];
                    if (urlencoded)
                    {
                        text2 = HttpValueCollection.UrlEncodeForToString(text2);
                    }
                    stringBuilder.Append(text2);
                }
                else
                {
                    for (int j = 0; j < values.Length; j++)
                    {
                        if (j > 0)
                        {
                            stringBuilder.Append('&');
                        }
                        stringBuilder.Append(value);
                        string text2 = values[j];
                        if (urlencoded)
                        {
                            text2 = HttpValueCollection.UrlEncodeForToString(text2);
                        }
                        stringBuilder.Append(text2);
                    }
                }
            }
        }
    }
    return stringBuilder.ToString();
}

internal static string UrlEncodeForToString(string input)
{
    return HttpUtility.UrlEncodeUnicode(input);
}
于 2013-11-01T09:28:33.893 に答える