有其他人处理过这个问题吗?我考虑在输入到数据库时过滤数据,但那样我就必须在各处放置过滤器,并且每个字符都需要检查。
还有其他建议吗?
编辑: 数据通常存储在不同长度的varchar列中。实际上,数据是从web表单(ASP.NET应用程序)上的用户输入的。因此,有时他们从MS Word等复制粘贴,这会导致出现奇怪的二进制字符。
我曾经看到过DotNet SqlClient从数据库中的nvarchar列“混淆”数据,我们的理论是这与“代理代码点”有关,参见:
http://www.siao2.com/2005/07/27/444101.aspx
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=rzaaxsurrogate.htm
SqlClient 似乎“解释”了一些字节,导致我们的 Xml 不再是格式良好的,转换为 nvarchar(max) 可以阻止这种情况发生(尽管这会对性能产生影响):
SELECT CONVERT(NVARCHAR(MAX), MyValue) FROM ...
CREATE TABLE test (
id int identity(1,1) not null primary key,
data nvarchar(50))
INSERT INTO test (data) values (char(0))
SELECT * FROM test FOR XML RAW
产生:
<row ID="1" data="�" />
这是编码的问题吗?还是xml格式不正确?如果是格式不正确,我无能为力。但对于编码...很遗憾ExecuteXmlReader
不允许您指定编码,但您可以将数据视为BLOB,并使用自己的编码和XmlReader
单独处理它。
如果数据很大,您可能需要使用ExecuteReader
和CommandBehavior.SequentialAccess
,并将其写入临时文件(Path.GetTempFileName()
)-然后将该文件作为Stream
与XmlReader
一起处理。
我已经在应用程序中的各个地方抽象了创建SqlParameter对象的过程,因此我将在那一点上清理输入。我的抽象方法创建并返回一个SqlParameter对象,用于调用存储过程。如果调用者想要一个varchar类型的参数,我将循环遍历他们想要转换为SqlParameter对象的字符串的每个字符,并过滤掉那些非法的二进制XML字符。这将消除不良数据首次进入数据库的问题。