日前使用 C# 开发一项工具时,需要获取一个 Web 服务的显示数据,由于该服务使用 GB2312 编码,使得本工具无法正常显示中文字符。本文简要记录问题解决方法。

默认编码支持

调用 GetEncodings 方法可以获取所有编码的列表,使用 GetEncoding 方法可以获取其他编码。

    using System.Net;
    using System.Text;
    // ...
    
    
    static int Main(string[] args)
    {
        // ...
        WebClient request = new WebClient();
        request.Encoding = Encoding.GetEncoding(936);
        // ...
    }

在本例中需要使用 GB2312 编码,EncodingInfo.Name 应为 GB2312,其 CodePage 为 936。上述代码将 request 的编码值改为 936,可以在后续的上传和下载中默认使用 GB2312 编码。

在 .NET Framework 环境下使用上述写法可以解决中文编码问题,但在 Core 环境下需要做出进一步设置。

.NET Core 的情况

.NET Framework 支持大量 Unicode 和 代码页编码,但在 .NET Core 直接提供的编码实现主要有 utf7(65000)utf8(65001)utf16(1200/1201)utf32(12000/12001)ASCII 等几种。

在 .NET Core 中,使用 Encoding.GetEncoding 方法设置没有默认支持的代码页后会抛出 System.NotSupportedException 异常,反映该编码不可用。

重新确认 CodePage 无误后,查询了 .NET Core 支持的编码形式,发现 936 编码得到了 .NET Framework 支持,在 .NET Core 中不受支持。

解决方法

在 Core 中使用所需的编码,需要在 CodePagesEncodingProvider 类扩展 EncodingProvider 以使用附加代码页。可以参考以下操作:

第一,在项目中引用附加代码页的程序集。通过 Nuget 下载最新的 System.Text.Encoding.CodePages 包,部署在项目中。

第二,在 CodePagesEncodingProvider.Instance 属性中检索 CodePagesEncodingProvider 对象并传递给 Encoding.RegisterProvider 方法。

    // 注册桌面支持的字符编码提供程序
    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

CodePagesEncodingProvider.Instance 属性是一个静态项,它提供了 .NET Framework 支持但当前平台不支持的代码页提供程序。Encoding.RegisterProvider 方法用于注册编码提供程序,为当前平台提供原本不支持的字符编码。