我有一个将对象序列化为字符串的方法,展示:
Shared Function Serialize(ByVal o As Object) As String
Dim rtnVal As String = ""
Dim x As New System.Xml.Serialization.XmlSerializer(o.GetType())
Using memStream As New MemoryStream
Dim stWriter As New System.IO.StreamWriter(memStream)
x.Serialize(stWriter, o)
rtnVal = Encoding.UTF8.GetString(memStream.GetBuffer())
End Using
Return rtnVal
End Function
使用此序列化数据,我现在将其插入 SQL 2012 数据库中的 XML 类型字段中。大多数时候,这段代码工作得很好,但对于特定对象,我得到“无效”字符,即错误“解析第 5 行字符 17 非法 xml 字符”。我查看了我的数据,它很干净,正如您在此处看到的:
<?xml version="1.0" encoding="utf-8"?>
<RatingDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<LenderName>dsfg</LenderName>
<VehiclePrice>345</VehiclePrice>
</RatingDetails>
一些窥探导致我执行 IsXMLChar 方法 - http://msdn.microsoft.com/en-us/library/system.xml.xmlconvert.isxmlchar%28v=vs.100%29.aspx - 使用它,我能够循环遍历序列化 XML 字符串中的每个字符。你瞧,我确实有无效数据。我的字符串末尾有 15 个“”字符 - WTF!?!
所以我对你们所有人的问题是,额外的“到底是从哪里来的,为什么当我检查快速 watch 中的字符串时看不到它们,以及如何首先阻止它们。
您的 ASP.NET,ewitkows
最佳答案
问题是您正在调用MemoryStream.GetBuffer
。根据MSDN article :
Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method; however, ToArray creates a copy of the data in memory.
要修复它,您可以调用 ToArray
来代替:
Shared Function Serialize(ByVal o As Object) As String
Dim rtnVal As String = ""
Dim x As New System.Xml.Serialization.XmlSerializer(o.GetType())
Using memStream As New MemoryStream
Dim stWriter As New System.IO.StreamWriter(memStream)
x.Serialize(stWriter, o)
rtnVal = Encoding.UTF8.GetString(memStream.ToArray())
End Using
Return rtnVal
End Function
但是,这仍然不是很有效。如果流包含大量数据,它会无缘无故地将整个数据复制到新数组中。为了让您安心,我建议使用 StreamReader 来读取 MemoryStream,而不是尝试自己解码它(但不要忘记返回到内存流的开头)在阅读之前先进行流式传输):
Public Function Serialize(ByVal o As Object) As String
Dim rtnVal As String = ""
Dim x As New System.Xml.Serialization.XmlSerializer(o.GetType())
Using memStream As New MemoryStream
Dim stWriter As New System.IO.StreamWriter(memStream)
x.Serialize(stWriter, o)
Dim reader As New StreamReader(memStream)
memStream.Position = 0 ' Seek to start of stream
rtnVal = reader.ReadToEnd()
End Using
Return rtnVal
End Function
关于asp.net - XmlSerializer 添加额外字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18472278/