HttpUtility.ParseQueryString與雙頻式Request參數解析
4 |
手邊有個需求,要把IIS Log Query String裡的參數解析出來,例如: "?a=LeftMenu&t=%u9ed1%u6697%u57f7%u884c%u7dd2&u=/Darkthread.aspx&_=1262748681109"。需求不難,但要拆解參數、UrlDecode,眉角還挺多的。原本已捲起袖子打算自己動手寫,頓時想到佛心的HttpUtility Class可能會內建,一找之下,果然發現了好東西HttpUtility.ParseQueryString!
送字串進去就傳回NameValueCollection,連%u9ed1這些Uncode編碼也會一併解好,十分方便。
static void Main(string[] args)
{
string query =
"?a=LeftMenu&t=%u9ed1%u6697%u57f7%u884c%u7dd2&u=/Darkthread.aspx&_=1262748681109";
NameValueCollection nvc =
HttpUtility.ParseQueryString(query);
foreach (string key in nvc.Keys)
{
Console.WriteLine("{0} => {1}", key, nvc[key]);
}
Console.Read();
}
執行結果:
a => LeftMenu
t => 黑暗執行緒
u => /Darkthread.aspx
_ => 1262748681109
看到這個方法,我想到前陣子網友三腳貓提了一個ASP串接ASP.NET的URL編碼問題,於是幫它想出一個新用途。我們都知道Query String編碼時有Encoding之分,例如: 黑暗執行緒用Big5編碼做UrlEncode會變成%b6%c2%b7t%b0%f5%a6%e6%ba%fc,此時用ASP.NET Request預設編碼(UTF-8)解析就會產生亂碼。
雖然我們可以修改ASP.NET Request的Encoding設定或ASP檔的Encoding設定,若產生URL的一方無法配合更改,而我們又不想為了部分Request更動整個ASP.NET Request的編碼設定,我想到可以搞出類似以下的做法,不管傳入Unicode或BIG5版的UrlEncode,都可以正確解析:
<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
string paramS = null;
if (Request.Url.Query.Length > 0 &&
Regex.IsMatch(
Request.RawUrl,
//利用以下特徵簡略(但草率)識別出BIG5 UrlEncode
"%[a-f][0-9a-f]", RegexOptions.IgnoreCase)
)
{
NameValueCollection nvc =
HttpUtility.ParseQueryString(
Request.RawUrl.Substring(Request.RawUrl.IndexOf("?") + 1),
Encoding.GetEncoding(950));
paramS = nvc["s"];
}
else
paramS = Request["s"];
Response.Write("s=" + paramS);
Response.End();
}
</script>
測試以下兩種URL,都可以正確解出"黑暗執行緒",不知道這樣可不可以稱為"支援雙頻"? 呵呵呵...
- Default.aspx?s=%u9ed1%u6697%u57f7%u884c%u7dd2
- Default.aspx?s=%b6%c2%b7t%b0%f5%a6%e6%ba%fc
【延伸閱讀】
Comments
# by Ark
Regex.IsMatch(Request.RawUrl, //利用以下特徵簡易識別出BIG5 UrlEncode "%[a-f][0-9a-f]%", RegexOptions.IgnoreCase) <==請教出處? 另求gb2312
# by Jeffrey
to Ark, 我校正了一下文字"//利用以下特徵簡略(但草率)識別出BIG5 UrlEncode"以免誤會,這個判別方法很不精準,原則上是抓BIG5的漢字範圍是從0xA440-0xC67E(REF: http://zh.wikipedia.org/wiki/%E5%A4%A7%E4%BA%94%E7%A2%BC),而假設一般的URL Encode中是不會用到%a0以上的字元,所以用這個粗略的方法,看到黑影就開槍。不過,其他如UTF-8、GB2312等透過UrlEncode也會產生類似特徵,要做到不同編碼自動識別,複雜度變高許多,就不是我這段輕鬆小品型程式碼可以涵蓋的了。
# by ALEX
請問若是使用VB的話,該如何改寫呢?
# by evan
剛好需要,太感謝了!