2013-11-01 12 views
9

私はそうように初期化されるユーザーコントロールでNameValueCollectionを持たない:私はこの上ToString()を呼び出すとのToString()は出力しない所望の結果

private NameValueCollection _nameValues = HttpUtility.ParseQueryString(Request.QueryString.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メソッドが目的の結果を出力するようにしますか?

+0

[URLクエリにNameValueCollectionの?](https://stackoverflow.com/questions/3865975/namevaluecollection-to-url-query) – dana

答えて

11

問題は、あなたのコード内の2つの実際のタイプがあります。最初の1つはSystem.Web.HttpValueCollectionで、これはToStringメソッドをオーバーライドして期待通りの結果を得、2つ目がToStringをオーバーライドしないSystem.Collection.Specialized.NameValueCollectionです。実際に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()); 
+0

作品の可能性のある重複を魔法のように。 – bump

2

文字列フォーマットを提供するのはNameValueCollectionではありません。その機能はHttpUtility.ParseQueryStringによって返される内部クラスSystem.Web.HttpValueCollectionにあります。

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

ここにはHttpValueCollectionクラスのメソッドがありますが、いくつかの変更を加えて使用することができます。名前と値のコレクションに.ToString()を呼び出す

// 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); 
} 
1

はちょうどあなたにそれが属する名前空間を提供します。

私はそれだけでない理由は、コレクション内の最初のだと仮定すると、あなたはそれのうち、キーと値をしたい疑う:

public static string ToString(this NameValueCollection nvc, int idx) 
{ 
    if(nvc == null) 
     throw new NullReferenceException(); 

    string key = nvc[idx]; 
    if(nvc.HasKeys() && !string.IsNullOrEmpty(key)) 
    { 
     return string.Concat(key, nvc.Get(key)); //maybe want some formatting here 
    } 

    return string.Empty; 
} 

var newUrl = String.Concat(_rootPath + "?" + nameValues.GetKey(0) + nameValues.Get(0)); 

あなたが拡張メソッドとしてこれを持つことができます

使用法:

NameValueCollection nvc = new NameValueCollection(); 
string foo = nvc.ToString(0); //gets key + value at index 0 
関連する問題