Explore. Dream. Discover.

Samuel Chen's life

Twenty years from now you will be more disappointed by
the things that you didn't do than by the ones you did do.
So throw off the bowlines. Sail away from the safe harbor.
Catch the trade winds in your sails.

Explore. Dream. Discover.
—— Mark Twain

2004年3月25日 星期四

在ASP.NET中使用字符编码


  • Title: 在ASP.NET中使用字符编码
  • Author: Samuel Chen
  • Email: samuel.net [at] gmail.com
  • Environment: .Net Framework 1.1, Win2k+
  • Keywords: ASP.NET, Encoding
  • Level: Intermediate
  • Description: 提交你的数据到不支持当前语言的后台系统/数据库
  • Section: ASP.NET
  • SubSection: General

本文亦发于CodeProject
下载源代码 45KB

Introduction


这篇文章介绍了如何提交你的数据到不支持当前语言的后台系统/数据库。

Background


当进行web application 开发时,经常会用到各种操作系统和数据库,其中不乏像SCO5之类不支持utf和gb2312这类双字或者多字节的操作系统或者数据库。因此,如何将你的文本数据完好的存入或者取出就成了一个重要的问题。

在我的一个项目中,需要将亚洲文字页面的内容保存到SCO5.05 + Informix7.3的后台数据库。如果直接使用sql语句保存,发现数据库相应的数据并不是传入的字符,而是变成了“à”,编码是0×7F的字符,所有的字符都是一样。这是什么原因呢?

这就是文字编码的问题。

打开项目的web.config文件,查看globalization 项的属性requestEncoding是utf-8,说明提交的数据是按照utf8编码的。由于SCO5.05不支持utf-8,因此直接将数据传入会导致数据错误(实际情况是变成0×7F),因此需要将数据先转换为SCO所能识别的西文ISO8859-1编码,然后再传递,而取出后再反向编码,这样就解决了我的问题。

Solution code


例如要将”你好Pi(\u03a0)”保存到数据库的memo字段中:


string unicodeStr = “你好Pi(u03a0)”;
OdbcConnection conn = new OdbcConnection();
System.Data.IDbCommand cmd = conn.CreateCommand();
conn.ConnectionString = “your connection string”;
cmd.Connection = conn;

// Encoding here
cmd.CommandText = “INSERT INTO encoding VALUES (’”
+ CEncoding.unicode_iso8859(unicodeStr) + “‘)”;
cmd.Connection = conn;

conn.Open();
cmd.ExecuteNonQuery();
conn.Close();


上面我用到了unicode_iso8859()这样的一个函数,该函数的作用是将utf-8编码的字符转换到iso8859-1编码,代码如下:


public class CEncoding {

public static string unicode_iso8859(string src) {

Encoding iso = Encoding.GetEncoding(”iso8859-1″);
Encoding unicode = Encoding.UTF8;
byte[] unicodeBytes = unicode.GetBytes(src);
return iso.GetString(unicodeBytes);
}

public static string iso8859_unicode(string src) {

Encoding iso = Encoding.GetEncoding(”iso8859-1″);
Encoding unicode = Encoding.UTF8;
byte[] isoBytes = iso.GetBytes(src);
return unicode.GetString(isoBytes);
}
}


打开数据库看看,是不是都变成了你不认识的西文符号?取出后,只需要使用iso8859_unicode()这一逆向函数进行反向编码即可,当然你也可以使用任何编码(比如gb2312)进行逆向编码以适应你的需要。

即使你使用的是adapter和dataset来填充datagrid,也可以很容易的使用这两个函数来进行转换,所需的代价是大约2~3倍的时间,自己斟酌了:)。代码如下:


OdbcAdapter adapter = new OdbcAdapter();
DataSet1 ds = new DataSet1();
DataGrid grid = new DataGrid();
OdbcConnection conn = new OdbcConnection();

// adapter, dataset and datagrid were initialized
conn.ConnectionString = “your connection string”;
adapter.Connection = conn;
conn.Open();
adapter.Fill(ds);

string xml = ds.GetXml();
ds.Clear();

// encoding here
ds.ReadXml(new System.IO.StringReader(CEncoding.iso8859_unicode(xml)));
grid.DataBind();

标签: , ,