.net - 如何检测和解决编码错误的Varchar数据?

标签 .net sql-server encoding utf-8

我的公司有一个基于第三方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/

相关文章:

c# - 使用 C# 从存储在 azure blob 存储上的 200gb 文本文件中读取一行

java - 连接到 MS Access 的 Eclipse 的深不可测的编码行为

ios - 当我在 XCode iOS 中触发推送通知时出现奇怪的字符

sql-server - 如何找到最长存储过程的名称?

windows - 使用 Media Foundation 进行硬件 H264 编码 ID3D11Texture2D

c# - 防止 Assembly.GetTypes() 加载依赖项

.net - 从网络共享编辑和运行 .NET 项目

.net - 我可以使用 silverlight 在客户端 PC 上写入文件吗

sql-server - SQL Server Linux 公共(public)预览版上的 xp_cmdshell

sql - 在 90 或更高版本的兼容模式下,ORDER BY 子句中不允许使用常量表达式