ASP.NET下QueryString不同字符编码间强制转换的解决方案
生活随笔
收集整理的這篇文章主要介紹了
ASP.NET下QueryString不同字符编码间强制转换的解决方案
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正常的情況下,現在asp.net的網站很多都直接使用UTF8來進行頁面編碼的,這與Javascript、缺省網站的編碼是相同的,但是也有相當一部分采用GB2312。
???? 對于GB2312的網站如果直接用javascript進行ajax數據提交,例如:http://www.xxx.com/accept.aspx?name=張三,或者說在UTF8的網站上用以下ASP.net的代碼進行提交,也是不行的。
WebRequest?request?=?WebRequest.Create("http://www.xxx.com/accept.aspx?name=張三");
????????request.Method?=?"POST";
????????HttpWebResponse?response?=?(HttpWebResponse)request.GetResponse();
???? 這樣在GB2312編碼的網站下得到Request.QueryString["name"]是亂碼,MS已經把編碼轉換這塊封裝好了。
???? 在UTF8編碼通訊和GB2312網站通訊方式下的編碼轉換方式有很多種實現:
???? 第一種:首先對要傳輸的字符進行UrlEncode,這種編碼后的字符在解碼時用UTF8編碼方式進行手工解碼,這樣保證結果一致,即使傳輸給的目標頁面時GB2312,結果都是一樣的,解碼方式如下代碼。
HttpUtility.UrlDecode(s,?Encoding.UTF8); ???? 這樣可以得到正確的張三,這要求在提交的時候先進行HttpUtility.UrlEncode編碼成UTF8先,然后再放到name=(編碼后的字符),這也是目前比較常用和普遍的解決方式,只是缺點有一個就是要告訴別人你先怎么怎么Url編碼先,然后再怎么怎么。
???? 第二種:比較另類一些,直接讀取客戶端提交的字節數據進行轉換,之所以Request.QueryString["name"]會是亂碼,是MS根據當前頁面的編碼進行轉換導致的,例如當前頁面編碼是GB2312,而人家提交的是UTF8,你沒用人家提交的UTF8編碼轉當然是亂碼,并不是人家傳過來就是亂碼。這時我們需要得到原始數據進行重新解碼,非常遺憾的是我并沒有找到直接提供頭部原始字節數據方法給我們用,沒關系,解剖下MS的源代碼,發現代碼如下:
????????public?NameValueCollection?QueryString?{
????????????get?{?
????????????????if?(_queryString?==?null)?{
????????????????????_queryString?=?new?HttpValueCollection();?
?
????????????????????if?(_wr?!=?null)
????????????????????????FillInQueryStringCollection();?
????????????????????_queryString.MakeReadOnly();
????????????????}
?
????????????????if?(_flags[needToValidateQueryString])?{
????????????????????_flags.Clear(needToValidateQueryString);?
????????????????????ValidateNameValueCollection(_queryString,?"Request.QueryString");?
????????????????}
?
????????????????return?_queryString;
????????????}
????????}
private?void?FillInQueryStringCollection()
{
????byte[]?queryStringBytes?=?this.QueryStringBytes;
????if?(queryStringBytes?!=?null)
????{
????????if?(queryStringBytes.Length?!=?0)
????????{
????????????this._queryString.FillFromEncodedBytes(queryStringBytes,?this.QueryStringEncoding);
????????}
????}
????else?if?(!string.IsNullOrEmpty(this.QueryStringText))
????{
????????this._queryString.FillFromString(this.QueryStringText,?true,?this.QueryStringEncoding);
????}
}
順便說一下,QueryString是在第一次被訪問時才初始化的,如果你的程序中沒有用到它,那個這個對象會一直保持空值,MS考慮了細節
???? 大家都看到了QueryStringBytes屬性,原型如下internal byte[] QueryStringBytes,這個就是原始的QueryString字節了。出招了:
Type?type?=?Request.GetType();
????????PropertyInfo?property?=?type.GetProperty("QueryStringBytes",
????????????BindingFlags.Instance??|?BindingFlags.IgnoreCase?|?BindingFlags.NonPublic);
????????byte[]?queryBytes?=?(byte[])property.GetValue(Request,?null);
????????string?querystring?=?HttpUtility.UrlDecode(queryBytes,?Encoding.UTF8); 再看看querystring是什么,哈哈name=張三。
???? 各種編碼的轉換都可以自己完成,畢竟得到提交的原始字節了,希望對大家有所幫助。
???? 對于GB2312的網站如果直接用javascript進行ajax數據提交,例如:http://www.xxx.com/accept.aspx?name=張三,或者說在UTF8的網站上用以下ASP.net的代碼進行提交,也是不行的。
WebRequest?request?=?WebRequest.Create("http://www.xxx.com/accept.aspx?name=張三");
????????request.Method?=?"POST";
????????HttpWebResponse?response?=?(HttpWebResponse)request.GetResponse();
???? 這樣在GB2312編碼的網站下得到Request.QueryString["name"]是亂碼,MS已經把編碼轉換這塊封裝好了。
???? 在UTF8編碼通訊和GB2312網站通訊方式下的編碼轉換方式有很多種實現:
???? 第一種:首先對要傳輸的字符進行UrlEncode,這種編碼后的字符在解碼時用UTF8編碼方式進行手工解碼,這樣保證結果一致,即使傳輸給的目標頁面時GB2312,結果都是一樣的,解碼方式如下代碼。
HttpUtility.UrlDecode(s,?Encoding.UTF8); ???? 這樣可以得到正確的張三,這要求在提交的時候先進行HttpUtility.UrlEncode編碼成UTF8先,然后再放到name=(編碼后的字符),這也是目前比較常用和普遍的解決方式,只是缺點有一個就是要告訴別人你先怎么怎么Url編碼先,然后再怎么怎么。
???? 第二種:比較另類一些,直接讀取客戶端提交的字節數據進行轉換,之所以Request.QueryString["name"]會是亂碼,是MS根據當前頁面的編碼進行轉換導致的,例如當前頁面編碼是GB2312,而人家提交的是UTF8,你沒用人家提交的UTF8編碼轉當然是亂碼,并不是人家傳過來就是亂碼。這時我們需要得到原始數據進行重新解碼,非常遺憾的是我并沒有找到直接提供頭部原始字節數據方法給我們用,沒關系,解剖下MS的源代碼,發現代碼如下:
????????public?NameValueCollection?QueryString?{
????????????get?{?
????????????????if?(_queryString?==?null)?{
????????????????????_queryString?=?new?HttpValueCollection();?
?
????????????????????if?(_wr?!=?null)
????????????????????????FillInQueryStringCollection();?
????????????????????_queryString.MakeReadOnly();
????????????????}
?
????????????????if?(_flags[needToValidateQueryString])?{
????????????????????_flags.Clear(needToValidateQueryString);?
????????????????????ValidateNameValueCollection(_queryString,?"Request.QueryString");?
????????????????}
?
????????????????return?_queryString;
????????????}
????????}
private?void?FillInQueryStringCollection()
{
????byte[]?queryStringBytes?=?this.QueryStringBytes;
????if?(queryStringBytes?!=?null)
????{
????????if?(queryStringBytes.Length?!=?0)
????????{
????????????this._queryString.FillFromEncodedBytes(queryStringBytes,?this.QueryStringEncoding);
????????}
????}
????else?if?(!string.IsNullOrEmpty(this.QueryStringText))
????{
????????this._queryString.FillFromString(this.QueryStringText,?true,?this.QueryStringEncoding);
????}
}
順便說一下,QueryString是在第一次被訪問時才初始化的,如果你的程序中沒有用到它,那個這個對象會一直保持空值,MS考慮了細節
???? 大家都看到了QueryStringBytes屬性,原型如下internal byte[] QueryStringBytes,這個就是原始的QueryString字節了。出招了:
Type?type?=?Request.GetType();
????????PropertyInfo?property?=?type.GetProperty("QueryStringBytes",
????????????BindingFlags.Instance??|?BindingFlags.IgnoreCase?|?BindingFlags.NonPublic);
????????byte[]?queryBytes?=?(byte[])property.GetValue(Request,?null);
????????string?querystring?=?HttpUtility.UrlDecode(queryBytes,?Encoding.UTF8); 再看看querystring是什么,哈哈name=張三。
???? 各種編碼的轉換都可以自己完成,畢竟得到提交的原始字節了,希望對大家有所幫助。
轉載于:https://www.cnblogs.com/zhujiechang/archive/2009/07/25/1530878.html
總結
以上是生活随笔為你收集整理的ASP.NET下QueryString不同字符编码间强制转换的解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javascript实现平滑的锚点
- 下一篇: 分组取最新记录的SQL