2013-11-01 17 views
9

Tôi có một NameValueCollection trong một usercontrol đó được khởi tạo như sau:ToString() của sao chép NameValueCollection không đầu ra mong muốn kết quả

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

Khi tôi gọi là ToString() về vấn đề này nó tạo ra một chuỗi truy vấn thích hợp mà tôi có thể sử dụng cho một url cập nhật.

Tuy nhiên, khi tôi copy NameValueCollection qua constructor của nó như sau:

var nameValues = new NameValueCollection(_nameValues); 

Và sau đó cố gắng tạo thành một url:

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

Nó ra một địa chỉ như thế này:

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

Làm cách nào để sao chép NameValueCollection sao cho phương thức ToString() xuất kết quả mong muốn?

+0

có thể trùng lặp của (https://stackoverflow.com/questions/3865975/namevaluecollection-to-url-query) – dana

Trả lời

11

vấn đề là có hai loại thực tế trong mã của bạn. Một nắm tay là System.Web.HttpValueCollection có phương pháp ToString overriden để có được kết quả bạn mong đợi và thứ hai là System.Collection.Specialized.NameValueCollection không ghi đè ToString. Những gì bạn có thể làm, nếu bạn thực sự cần sử dụng System.Collection.Specialized.NameValueCollection là tạo một phương thức mở rộng.

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

và sử dụng nó: [? NameValueCollection để truy vấn URL]

var newUrl = String.Concat(_rootPath,nameValues.ToQueryString()); 
+0

trình như một say mê. – bump

2

Nó không phải là NameValueCollection cung cấp định dạng chuỗi. Chức năng đó nằm trong lớp nội bộ System.Web.HttpValueCollection được trả lại bằng HttpUtility.ParseQueryString.

Vì vậy, bạn sẽ không thể đạt được hành vi này bằng cách sử dụng chức năng được tích hợp sẵn. Đặt cược tốt nhất của bạn là tạo một phương thức mở rộng định dạng các giá trị theo định dạng URL.

Đây là phương pháp từ lớp HttpValueCollection - bạn có thể sử dụng nó với một số sửa đổi.

// 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

Calling .ToString() trên một bộ sưu tập giá trị tên sẽ chỉ cung cấp cho bạn không gian tên nó thuộc về.

tôi nghi ngờ bạn muốn khóa và giá trị ra khỏi nó, Giả sử rằng đó là lần đầu tiên trong bộ sưu tập tại sao không chỉ làm:

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

Bạn có thể có này như là một phương pháp khuyến nông:

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; 
} 

Cách sử dụng:

NameValueCollection nvc = new NameValueCollection(); 
string foo = nvc.ToString(0); //gets key + value at index 0 
Các vấn đề liên quan