﻿# 如何解決字集混亂的問題

前天替一個網友解決了一個 Encoding 混亂的問題：ASP.net 傳遞中文至Web Service 亂碼問題，像這種這個問題最常出現在「非 Unicode 的系統」裡，像這個案例就是他們的 Web Service 是用 [PHP](http://www.php.net/ "PHP") + [NuSOAP](http://dietrich.ganx4.com/nusoap/ "NuSOAP") 開發的，因為預設就是用 ISO-8859-1 的字集做資料的編碼與傳輸，所以資料在同樣的字集傳輸下，在非原生(Non-Native)支援 Unicode 的程式語言下很自然的不會發現問題，但是一到了 .NET 就不一樣了，.NET 是一個打從骨子裡支援 Unicode 的架構，所以對 Encoding 是很敏感的。

所以問題要解決就要有一些技巧了，我先解釋一下問題好了，如下：

目前的運作環境：

-   目前我要用 .NET 呼叫一個 Web Service
    
-   這個 Web Service 呼叫的編碼字集(Request Encoding)與回傳的編碼字集(Response Encoding)都是 ISO-8859-1
    

要讓 .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 才看的懂「中文」，也才不會出現亂碼。

以下是原始碼（含註解）說明：

```csharp
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);
    }
}
```

這一篇文章對初學者來說有點太深了，建議多查詢一些跟 Encoding 相關的資料來看看，多看一些原始碼培養一些感覺。

相關連結

-   [瞭解編碼](http://msdn2.microsoft.com/zh-tw/library/ms404377.aspx)
    
-   [使用 Unicode 編碼方式](http://msdn2.microsoft.com/zh-tw/library/zs0350fy.aspx)
    
-   [將基底型別編](http://msdn2.microsoft.com/zh-tw/library/1w71hb4e.aspx)
    
-   [編碼和當地語系化](http://msdn2.microsoft.com/zh-tw/library/h6270d0z.aspx)
    
-   [System.Text 命名空間](http://msdn2.microsoft.com/zh-tw/library/system.text.aspx)
    
-   [Encoding 類別](http://msdn2.microsoft.com/zh-tw/library/system.text.encoding.aspx "Encoding 類別")
