最近在一个项目上碰到了一个很搞的问题,不知道有何好的解决办法,请不吝赐教,万分感激!!!问题是这样的:
1、程序所有测试在简体中文Windows 2003 server系统中进行,一点问题都没有;
2、正式环境:windows 2003 server 英文版,加装简体中文包
3、当在web.config中加了一个配置项:
<system.web>
<globalization fileEncoding="gb2312" requestEncoding="gb2312" responseEncoding="gb2312" culture="zh-CN" />
时,从页面提交的Textbox中的中文内容到数据库就全是乱码,如果把 requestEncoding="gb2312"改为 requestEncoding="utf-8"则写入数据库不会乱码,下面第4点中的短信也不会乱码,但客户端上传到服务器上的文件,若文件名称是中文的,则上传后的文件也变成了乱码的。
4、因为在系统中用到华为的MAS发送短信,而如果不加第3点的配置,则发送的短信全都是乱码,郁闷啊!
5、程序采用三层开发,页面用户控件的方式,不方便每个页面指定编码。真不知道怎么搞了,左右都不是,所有这些问题,若服务器操作系统换为简体中文的则都是好的了,但是客户的服务器必须是安装英文版的,实在是郁闷啊!!!
1、程序所有测试在简体中文Windows 2003 server系统中进行,一点问题都没有;
2、正式环境:windows 2003 server 英文版,加装简体中文包
3、当在web.config中加了一个配置项:
<system.web>
<globalization fileEncoding="gb2312" requestEncoding="gb2312" responseEncoding="gb2312" culture="zh-CN" />
时,从页面提交的Textbox中的中文内容到数据库就全是乱码,如果把 requestEncoding="gb2312"改为 requestEncoding="utf-8"则写入数据库不会乱码,下面第4点中的短信也不会乱码,但客户端上传到服务器上的文件,若文件名称是中文的,则上传后的文件也变成了乱码的。
4、因为在系统中用到华为的MAS发送短信,而如果不加第3点的配置,则发送的短信全都是乱码,郁闷啊!
5、程序采用三层开发,页面用户控件的方式,不方便每个页面指定编码。真不知道怎么搞了,左右都不是,所有这些问题,若服务器操作系统换为简体中文的则都是好的了,但是客户的服务器必须是安装英文版的,实在是郁闷啊!!!
其实所有问题的起因都是这个MAS,后面加的,否则之前所有问题都没有,加了这个东西做了个接口,出现这个尴尬的局面!
一 编码概述
例1.
string str = "中文123";
Response.Write(str.Length);
Encoding gb = Encoding.GetEncoding("gb2312");
byte[] bytes = gb.GetBytes(str);
char[] chars = gb.GetChars(bytes);
str = gb.GetString(bytes);
StreamWriter sw = new StreamWriter("1.txt");
sw.Write(chars);
sw.Close();
StreamWriter sw2 = new StreamWriter("2.txt",false,gb);
sw2.Write(str);
sw2.Close();
二 易产生乱码的情况
非UNICODE程序在不同语言环境间移植时的乱码
非UNICODE程序中的字符串,都是以某种ANSI编码形式存在的.如果程序运行时的语言环境与开发时的语言环境不同,将会导致ANSI字符串的显示失败.
由于客观原因,有时候我们必须在中文操作系统下运行非UNICODE的日文软件,这时我们可以采用一些工具,比如,南极星,AppLocale等,暂时的模拟不同的语言环境.
网页提交字符串
当页面中的表单提交字符串时,首先把字符串按照当前页面的编码,转化成字节串.然后再将每个字节转化成”%XX”的格式提交到Web服务器.比如,一个编码为GB2312的页面,提交”中”这个字符串时,提交给服务器的内容为”%D6%D0”.
在服务器端,Web服务器把收到的”%D6%D0”转换成[0XD6,0XD0]两个字节,然后再根据GB2312编码规则得到”中”字.
默认情况下,当提交”%D6%D0”给服务器时,将返回[0X00D6,0X00D0]两个UNICODE字符,而不是返回一个”中”字符.所以出现乱码.
从数据库读取字符串
通过数据库客户端(如ODBC/JDBC)从数据库服务器中读取字符串时,客户端需要从服务器获知所使用的ANSI编码.当数据库服务器发送字节流给客户端时,客户端负责将字节流按照正确的编码转化成UNICODE字符串.
电子邮件中的字符串
当一段Text或者HTML通过电子邮件传送时,发送的内容首先通过一种指定的字符编码转化成”字节串”,然后再把”字节串”通过一种指定的传输编码(Content-Transfer-Encoding)进行转化得到另一串”字节串”;
最常用的Content-Transfer-Encoding有Base64和Quoted-Printable两种.
邮件标题编码
邮件的标题,用了一种更简短的格式来标注”字符编码”和”传输编码”.比如,标题内容为”中”,则在邮件源代码中表示为:
//正确的标题格式
Subject:=?GB2312?B?1tA=?=
第一个”=?”与”?”中间的部分指定了字符编码,在这个例子中指定的是GB2312.
“?”与”?”中间的”B”代表Base64.如果是”Q”则代表Quoted-Printable.
最后”?”与”?=”之间的部分,就是经过GB2312转化成字节串,再经过Base64转化后的标题内容.
如果”传输编码”改为Quoted-Printable,同样,如果标题内容为”中”:
Subject:=?GB2312?Q=D6=D0?=
例2.
string str = "中文123";
Encoding gb = Encoding.GetEncoding("gb2312");
byte[] bytes = gb.GetBytes(str);
Encoding ServerOK = Encoding.GetEncoding("gb2312");
string strServer = ServerOK.GetString(bytes);
Response.Write("正确转换后的字符串为:"+strServer);
strServer = Encoding.Unicode.GetString(bytes);
Response.Write("错误转换后的字符串为:"+strServer);
三 ASP.NET下的编码
Web.config文件全球化:
<globalization requestEncoding=”utf-8” responseEncoding=”utf-8”/>
requestEncoding是app请求时的编码,responseEncoding是IIS响应编码
Response.ContentEncoding:获取或设置输出流的HTTP字符集.
HttpRequest.ContentEncoding: 表示客户端的字符集的Encoding对象.
页面charset属性
例3.
string utfinfo = "document.write(\"alert('aa你好么??');\");";
string gb2312info = "";
Encoding utf8 = Encoding.UTF8;
Encoding gb2312 = Encoding.GetEncoding("gb2312");
byte[] uinicodeBytes = utf8.GetBytes(utfinfo);
byte[] asciiBytes = Encoding.Convert(utf8, gb2312, unicodeBytes);
char[] asciiChars = new char[gb2312, GetCharCount(asciiBytes, 0,asciiBytes.Length)];
gb2312.GetChars(asciiBytes,0,asciiBytes.Length,asciiChars,0);
gb2312info = new string(asciiChars);