将系统的内部类:HttpValueCollection 移到自己的系统中,使其能方便的解析id=1&name=张三&sex=男这样的字符串参数 querystring
引子:
其它成员做了一个棵树,treenode 的 Value值是这样一个串 "id=1&name=张三&sex=男",按普通做法的话,进行这个字符串拆分,用substring 和 split 两个方法就可以做到了.但是看到这样一个串我觉得和URL的QueryString是一样的.我就想用Request["id"]这样来得到这个字符串中id对应的"1"这个值.我一开始觉得HttpRequest的构造类肯定会有这样一个参数,new 实例的时候将这个querystring传进来就可以自动解析了.但是当我这样做的时候发现,HttpRequest的构造方法只有一个如下:
// 初始化 System.Web.HttpRequest 对象。
//
// 参数:
// url:
// 有关当前请求的 URL 的信息。
//
// queryString:
// 与请求一起发送的整个查询字符串('?' 之后的所有内容)。
//
// filename:
// 与请求关联的文件的名称。
public HttpRequest(string filename, string url, string queryString);
我试图这样构造方法
但是出现一个这样的错误:
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.UriFormatException: 无效的 URI: 此 URI 为空。
看来是要有一个uri才可以,于是这样
这下可以正常用rs["id"]得到对应的值了,看样子是可以了.解决了这个问题.
但是我后来越看越觉得加了这么一串http://www.sina.com.cn/比较恶心,很想将其去掉,于是就没事开始折腾了.
开始折腾
打开.net Reflector反编译了httprequest对象,
发现其是看到sealed知道是一个密封类了,
没办法继承修改,再看成员
看来是HttpValueCollection 类型,看其元数据
看来是一个内部类,不能被外部工程所修改,于是我又想到一个很WS的办法,完全COPY里面的代码出来,实现自己的一个HttPValueCollection类型,能够实现 HttPValueCollection list = new HttPValueCollection(string queryString)就可以了,这样就可以去掉那个让人添加恶心的URI标记.
实现如下效果
string id = rs["id"].ToString();
完整的HTTPValueCollection代码如下:
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.Runtime.Serialization;
namespace HttpWeb
{
public class HttpValueCollection : NameValueCollection
{
// Methods
public HttpValueCollection()
: base((IEqualityComparer)StringComparer.OrdinalIgnoreCase)
{
}
public HttpValueCollection(int capacity)
: base(capacity, (IEqualityComparer)StringComparer.OrdinalIgnoreCase)
{
}
public HttpValueCollection(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public HttpValueCollection(string str, bool readOnly, bool urlencoded, Encoding encoding)
: base((IEqualityComparer)StringComparer.OrdinalIgnoreCase)
{
if (!string.IsNullOrEmpty(str))
{
this.FillFromString(str, urlencoded, encoding);
}
base.IsReadOnly = readOnly;
}
internal void Add(HttpCookieCollection c)
{
int count = c.Count;
for (int i = 0; i < count; i++)
{
HttpCookie cookie = c.Get(i);
base.Add(cookie.Name, cookie.Value);
}
}
internal void FillFromEncodedBytes(byte[] bytes, Encoding encoding)
{
int num = (bytes != null) ? bytes.Length : 0;
for (int i = 0; i < num; i++)
{
string str;
string str2;
int offset = i;
int num4 = -1;
while (i < num)
{
byte num5 = bytes[i];
if (num5 == 0x3d)
{
if (num4 < 0)
{
num4 = i;
}
}
else if (num5 == 0x26)
{
break;
}
i++;
}
if (num4 >= 0)
{
str = HttpUtility.UrlDecode(bytes, offset, num4 - offset, encoding);
str2 = HttpUtility.UrlDecode(bytes, num4 + 1, (i - num4) - 1, encoding);
}
else
{
str = null;
str2 = HttpUtility.UrlDecode(bytes, offset, i - offset, encoding);
}
base.Add(str, str2);
if ((i == (num - 1)) && (bytes[i] == 0x26))
{
base.Add(null, string.Empty);
}
}
}
internal void FillFromString(string s)
{
this.FillFromString(s, false, null);
}
internal void FillFromString(string s, bool urlencoded, Encoding encoding)
{
int num = (s != null) ? s.Length : 0;
for (int i = 0; i < num; i++)
{
int startIndex = i;
int num4 = -1;
while (i < num)
{
char ch = s[i];
if (ch == '=')
{
if (num4 < 0)
{
num4 = i;
}
}
else if (ch == '&')
{
break;
}
i++;
}
string str = null;
string str2 = null;
if (num4 >= 0)
{
str = s.Substring(startIndex, num4 - startIndex);
str2 = s.Substring(num4 + 1, (i - num4) - 1);
}
else
{
str2 = s.Substring(startIndex, i - startIndex);
}
if (urlencoded)
{
base.Add(HttpUtility.UrlDecode(str, encoding), HttpUtility.UrlDecode(str2, encoding));
}
else
{
base.Add(str, str2);
}
if ((i == (num - 1)) && (s[i] == '&'))
{
base.Add(null, string.Empty);
}
}
}
internal void MakeReadOnly()
{
base.IsReadOnly = true;
}
internal void MakeReadWrite()
{
base.IsReadOnly = false;
}
internal void Reset()
{
base.Clear();
}
public override string ToString()
{
return this.ToString(true);
}
internal virtual string ToString(bool urlencoded)
{
return this.ToString(urlencoded, null);
}
internal virtual string ToString(bool urlencoded, IDictionary excludeKeys)
{
int count = this.Count;
if (count == 0)
{
return string.Empty;
}
StringBuilder builder = new StringBuilder();
bool flag = (excludeKeys != null) && (excludeKeys["__VIEWSTATE"] != null);
for (int i = 0; i < count; i++)
{
string key = this.GetKey(i);
if (((!flag || (key == null)) || !key.StartsWith("__VIEWSTATE", StringComparison.Ordinal)) && (((excludeKeys == null) || (key == null)) || (excludeKeys[key] == null)))
{
string str3;
if (urlencoded)
{
key = HttpUtility.UrlEncodeUnicode(key);
}
string str2 = !string.IsNullOrEmpty(key) ? (key + "=") : string.Empty;
ArrayList list = (ArrayList)base.BaseGet(i);
int num3 = (list != null) ? list.Count : 0;
if (builder.Length > 0)
{
builder.Append('&');
}
if (num3 == 1)
{
builder.Append(str2);
str3 = (string)list[0];
if (urlencoded)
{
str3 = HttpUtility.UrlEncodeUnicode(str3);
}
builder.Append(str3);
}
else if (num3 == 0)
{
builder.Append(str2);
}
else
{
for (int j = 0; j < num3; j++)
{
if (j > 0)
{
builder.Append('&');
}
builder.Append(str2);
str3 = (string)list[j];
if (urlencoded)
{
str3 = HttpUtility.UrlEncodeUnicode(str3);
}
builder.Append(str3);
}
}
}
}
return builder.ToString();
}
}
}