NameValueCollection详解及Url编码与解码
参考:
http://www.cnblogs.com/mrray/archive/2011/09/28/2193831.html
1.NameValueCollection类集合是基于 NameObjectCollectionBase 类。
但与 NameObjectCollectionBase 不同,该类在一个键下存储多个字符串值(就是键相同,值就连接起来如下例子)。该类可用于标头、查询字符串和窗体数据。
每个元素都是一个键/值对。NameValueCollection 的容量是 NameValueCollection 可以保存的元素数。
NameValueCollection 的默认初始容量为零。随着向 NameValueCollection 中添加元素,容量通过重新分配按需自动增加。
如下例子:
NameValueCollection myCol = new NameValueCollection(); myCol.Add("red", "rojo");//如果键值red相同结果合并 rojo,rouge myCol.Add("green", "verde"); myCol.Add("blue", "azul"); myCol.Add("red", "rouge");
2.NameValueCollection与Hashtable的区别
a.引用区别
hashtable:using System.Collections;
NameValueCollection:using System.Collections.Specialized;
b.键是否重复
NameValueCollection:允许重复.
HashTable是键-值集合,但键不能出现重复.
Hashtable ht = new Hashtable();
ht.Add("key","value");
ht.Add("key", "value1"); //出错
ht["key"] = "value1"; //正确
3.初始化NameValueCollection
初始化NameValueCollection需引用using System.Collections.Specialized;
完整例子源码:
using System; using System.Collections; using System.Collections.Specialized; namespace SamplesNameValueCollection { class Program { public static void Main() { //初始化NameValueCollection需引用using System.Collections.Specialized; NameValueCollection myCol = new NameValueCollection(); myCol.Add("red", "rojo");//如果键值red相同结果合并 rojo,rouge myCol.Add("green", "verde"); myCol.Add("blue", "azul"); myCol.Add("red", "rouge"); // Displays the values in the NameValueCollection in two different ways. //显示键,值 Console.WriteLine("Displays the elements using the AllKeys property and the Item (indexer) property:"); PrintKeysAndValues(myCol); Console.WriteLine("Displays the elements using GetKey and Get:"); PrintKeysAndValues2(myCol); // Gets a value either by index or by key. //按索引或值获取 Console.WriteLine("Index 1 contains the value {0}.", myCol[1]);//索引1的值 Console.WriteLine("Key \"red\" has the value {0}.", myCol["red"]);//键为red的对应值rouge Console.WriteLine(); // Copies the values to a string array and displays the string array. String[] myStrArr = new String[myCol.Count]; myCol.CopyTo(myStrArr, 0); Console.WriteLine("The string array contains:"); foreach (String s in myStrArr) Console.WriteLine(" {0}", s); Console.WriteLine(); //查找green键值然后删除 myCol.Remove("green"); Console.WriteLine("The collection contains the following elements after removing \"green\":"); PrintKeysAndValues(myCol); //清空集合 myCol.Clear(); Console.WriteLine("The collection contains the following elements after it is cleared:"); PrintKeysAndValues(myCol); } //显示键,值 public static void PrintKeysAndValues(NameValueCollection myCol) { IEnumerator myEnumerator = myCol.GetEnumerator(); Console.WriteLine(" KEY VALUE"); foreach (String s in myCol.AllKeys) Console.WriteLine(" {0,-10} {1}", s, myCol[s]); Console.WriteLine(); } //显示索引, 键,值 public static void PrintKeysAndValues2(NameValueCollection myCol) { Console.WriteLine(" [INDEX] KEY VALUE"); for (int i = 0; i < myCol.Count; i++) Console.WriteLine(" [{0}] {1,-10} {2}", i, myCol.GetKey(i), myCol.Get(i)); Console.WriteLine(); } } }
4.NameValueCollection遍历
与Hashtable相似:
NameValueCollection myCol = new NameValueCollection(); myCol.Add("red", "rojo");//如果键值red相同结果合并 rojo,rouge myCol.Add("green", "verde"); myCol.Add("blue", "azul"); myCol["red"] = "dd"; foreach (string key in myCol.Keys) { Console.WriteLine("{0}:{1}", key, myCol[key]); } Console.ReadLine();
I use it like:
private NameValueCollection _header;
/// 语言
/// </summary>
public string Language
{
get { return _header["Language"] ?? ""; }
}
NameValueCollection geeparameters = new NameValueCollection();
if (!string.IsNullOrEmpty(getValidate))
{
geparameters = HttpUtility.ParseQueryString(getValidate);
}
var Challenge = geeparameters["Challenge"];
var Validate = geeparameters["Validate"];
var Seccode = geeparameters["Seccode"];
上面的方法:Request.QueryString,它会把传入的URL进行分析,并把结果保存在一个键值(key value)的Collection中,我们只要通过设置key值,就可以返回这个key所对应的value了。
假设这个URL不是通过请求进来的,我们是没有办法通过Request来获取URL的参数值的
其实上面的string id = Request.QueryString["id"]; 也可以写成
System.Collections.Specialized.NameValueCollection col = Request.QueryString;
string strID = col[”id”];
所以让我们来构造这个NameValueCollection吧!
/// <summary> /// 测试. /// </summary> public void Test() { string pageURL = "http://www.google.com.hk/search?hl=zh-CN&source=hp&q=%E5%8D%9A%E6%B1%87%E6%95%B0%E7%A0%81&aq=f&aqi=g2&aql=&oq=&gs_rfai="; Uri uri = new Uri(pageURL); string queryString = uri.Query; NameValueCollection col = GetQueryString(queryString); string searchKey = col["q"]; //结果 searchKey = "博汇数码" } /// <summary> /// 将查询字符串解析转换为名值集合. /// </summary> /// <param name="queryString"></param> /// <returns></returns> public static NameValueCollection GetQueryString(string queryString) { return GetQueryString(queryString, null, true); } /// <summary> /// 将查询字符串解析转换为名值集合. /// </summary> /// <param name="queryString"></param> /// <param name="encoding"></param> /// <param name="isEncoded"></param> /// <returns></returns> public static NameValueCollection GetQueryString(string queryString, Encoding encoding, bool isEncoded) { queryString = queryString.Replace("?", ""); NameValueCollection result = new NameValueCollection(StringComparer.OrdinalIgnoreCase); if (!string.IsNullOrEmpty(queryString)) { int count = queryString.Length; for (int i = 0; i < count; i++) { int startIndex = i; int index = -1; while (i < count) { char item = queryString[i]; if (item == '=') { if (index < 0) { index = i; } } else if (item == '&') { break; } i++; } string key = null; string value = null; if (index >= 0) { key = queryString.Substring(startIndex, index - startIndex); value = queryString.Substring(index + 1, (i - index) - 1); } else { key = queryString.Substring(startIndex, i - startIndex); } if (isEncoded) { result[MyUrlDeCode(key, encoding)] = MyUrlDeCode(value, encoding); } else { result[key] = value; } if ((i == (count - 1)) && (queryString[i] == '&')) { result[key] = string.Empty; } } } return result; } /// <summary> /// 解码URL. /// </summary> /// <param name="encoding">null为自动选择编码</param> /// <param name="str"></param> /// <returns></returns> public static string MyUrlDeCode(string str, Encoding encoding) { if (encoding == null) { Encoding utf8 = Encoding.UTF8; //首先用utf-8进行解码 string code = HttpUtility.UrlDecode(str.ToUpper(), utf8); //将已经解码的字符再次进行编码. string encode = HttpUtility.UrlEncode(code, utf8).ToUpper(); if (str == encode) encoding = Encoding.UTF8; else encoding = Encoding.GetEncoding("gb2312"); } return HttpUtility.UrlDecode(str, encoding); }
说明
- 对于下面的编码方式中,Baidu是使用gb2312,而Google是使用UTF8的,所以这些编码如何解释呢?解决办法就是如MyUrlDeCode方法所写的,把编码进行一次解码,再把解码后的字符串进行编码,再对字符串进行比较,如果是相同的,那就是使用了这种编码的。还要注意进行ToUpper字符串。
- //博汇数码.
string baidu = HttpUtility.UrlDecode("wd=%B2%A9%BB%E3%CA%FD%C2%EB");
string google = HttpUtility.UrlDecode("q=%E5%8D%9A%E6%B1%87%E6%95%B0%E7%A0%81"); - 关于return GetQueryString(queryString, null, true); 如果你传入的是null,那就是表示你无法确认编码是gb2312还是UTF8,当你确认编码的,可以直接传入编码类型,比如return GetQueryString(queryString, Encoding.UTF8, true);
- 需要注意queryString = queryString.Replace("?", "");把?给过滤掉。
- %B2%A9%BB%E3%CA%FD%C2%EB = %B2%A9 %BB%E3 %CA%FD %C2%EB(博汇数码gb2312)
- %E5%8D%9A%E6%B1%87%E6%95%B0%E7%A0%81 = %E5%8D%9A %E6%B1%87 %E6%95%B0 %E7%A0%81(博汇数码utf-8)
此随笔或为自己所写、或为转载于网络。仅用于个人收集及备忘。

浙公网安备 33010602011771号