我的公司有一个基于第三方Webmail系统构建的CRM产品。我们使用其基础数据库,并使用我们自己的其他数据库对其进行了扩展。客户不仅可以使用我们的产品,还可以直接登录Webmail系统。
Webmail数据库使用SQL_Latin1_General_CP1_CI_AS编码,联系人姓名存储在varchar列中,而不是nvarchar中。
我们的产品和Webmail产品均提供Content-Type的页面:text / html charset = utf-8
如果客户在网络邮件(第三方系统)中创建了一个名字为“Céline”的联系人,则该联系人最终将以“Céline”的形式存储在数据库中。这是因为Webmail似乎先将数据从utf-8转换为latin-1,然后再将其存储在数据库中。 utf-8字符'é'存储为两个字节,在latin-1中被解释为两个字符:“Ô
但是,当检索数据并将其显示在网络邮件中时,它会正确显示为“Céline”
问题是:从我们的CRM系统读取/写入联系人时,如果将名字设置为“Céline”,则将其存储为“Céline”,而不是首先转换为latin-1“Céline”
反之亦然,如果您在网络邮件中创建Céline,则它在我们的CRM产品中显示为Céline,因为它没有从latin-1转换为utf-8
我们的产品已实现法国国际化,并且已经投入生产了几个月,因此使用这两种编码方法的系统中都有大量数据。
我可以使用以下方法将latin-1转换为utf-8:
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(Convert.ToString(obj))
string fix2 = Encoding.UTF8.GetString(bytes).Trim(); //from iso-8859-1 (latin-1) to utf-8
但这仅适用于在存储之前将数据正确转换为latin-1的情况。因此,我真正需要的是一种确定记录中的数据是utf-8编码的字符串还是latin-1编码的字符串的方法。
或者,向前发展,我需要一种模仿网络邮件在做什么的方法,并使对数据库的所有写入操作首先从utf-8转换为latin-1,所有读取操作从latin-1转换为utf-8。
有任何想法吗?如果您需要其他信息/说明,请告诉我。
最佳答案
一些澄清。在字符编码之间转换字节流(这将修改字节)与使用不同的字符编码解释字节流(这不会修改字节,只是以不同的方式显示)之间有区别。您的Webmail应用程序不会在到数据库的途中转换UTF-8
字符,而是(错误地)重新解释了字节流。
是否可以检测到编码错误的字符?
从理论上讲,没有。解释为ISO-8859-1
的字符完全有效。在实践中,您可以手工搜索不常见的字符(例如本例中的Ã),并能够发现不一致之处。
我需要一种模仿网络邮件正在做什么的方法
要将C#中的字符串从UTF-8
重新解释为ISO-8859-1
,您可以使用以下行(请记住,从数据库返回时执行相反的操作)
Encoding.GetEncoding("iso-8859-1").GetString(Encoding.UTF8.getBytes("Some text"))
关于.net - 如何检测和解决编码错误的Varchar数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10420889/