前天替一個網友解決了一個 Encoding 混亂的問題:ASP.net 傳遞中文至Web Service 亂碼問題,像這種這個問題最常出現在「非 Unicode 的系統」裡,像這個案例就是他們的 Web Service 是用 PHP + NuSOAP 開發的,因為預設就是用 ISO-8859-1 的字集做資料的編碼與傳輸,所以資料在同樣的字集傳輸下,在非原生(Non-Native)支援 Unicode 的程式語言下很自然的不會發現問題,但是一到了 .NET 就不一樣了,.NET 是一個打從骨子裡支援 Unicode 的架構,所以對 Encoding 是很敏感的。
所以問題要解決就要有一些技巧了,我先解釋一下問題好了,如下:
目前的運作環境:
要讓 .NET 的正確的處理中文字串的話,使用 ISO-8859-1 是不行的,一定要轉換成 Big5 或 Unicode 才行,否則所有得到的字串都會是問號 ( ? )或亂碼。
這個 Web Service 是有問題的,因為他 Encoding 宣告的是 ISO-8859-1 但是其內容卻是用 Big5 編碼(其實 ISO-8859-1 與 Big5 的編碼是重疊的),所以我們必須要將傳出去的字串先變成用 ISO-8859-1 編碼的字串,再傳送給這個 Web Service,等得到資料後再將取得的 ISO-8859-1 轉成 Big5 編碼,這時 .NET 才看的懂「中文」,也才不會出現亂碼。
以下是原始碼(含註解)說明:
[code:c#]
using System;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Text;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
tw.edu.nccu.dlll.ECScanner ec = new tw.edu.nccu.dlll.ECScanner();
// 指定發送的 Encoding
ec.RequestEncoding = Encoding.GetEncoding("ISO-8859-1");
// 先將 Unicode 的字串轉成 Big5 的字元陣列
byte[] bBIG5 = Encoding.GetEncoding("big5").GetBytes("中國文化史");
// 再將 Big5 的字元陣列轉成 ISO-8859-1 的字串
// (因為ISO-8859-1跟Big5是重疊的字集才可以這樣用)
string requestString = Encoding.GetEncoding("ISO-8859-1").GetString(bBIG5);
// << 執行 Web Service 方法 >>
string rtn = ec.ecs_combin(requestString);
// 將取得後的字串以 ISO-8859-1 取得字元陣列
bBIG5 = Encoding.GetEncoding("ISO-8859-1").GetBytes(rtn);
// 再將 ISO-8859-1 的字元陣列轉成 Big5 編碼的字串
rtn = Encoding.GetEncoding("big5").GetString(bBIG5);
// 這時才會得到可以正常讀取的 .NET 字串
Response.Write(rtn);
}
}
[/code]
這一篇文章對初學者來說有點太深了,建議多查詢一些跟 Encoding 相關的資料來看看,多看一些原始碼培養一些感覺。
相關連結