2013-08-27 104 views
2

我有一個序列化對象的字符串的方法,表現出:XmlSerializer的添加額外的字符

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 

使用該序列化的數據,我現在將其插入XML類型的字段在我的SQL數據庫2012 。大多數情況下,這段代碼工作得很好,但對於某個特定的對象,我收到了「無效」字符,即錯誤「解析第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!?!

因此,我向你們提出的所有問題都是,額外的'來自何處,爲什麼當我在快速監視中檢查字符串時不能看到它們,以及如何首先防止它們。

此致在ASP.NET,ewitkows

+0

在哪裏你實例化'Encoding'對象?發佈該代碼。 –

+0

謝謝@KarlAnderson,但不,我沒有實例化,所有的代碼就在那裏.. – ewitkows

+0

@KarlAnderson,編碼是類名(即'System.Text.Encoding')。 'UTF8'是該類的共享屬性,所以不需要實例化來使用它。 –

回答

4

問題是你在呼喚MemoryStream.GetBuffer按照MSDN article:。

注意,緩衝區包含的分配字節,這可能是未使用的。例如,如果字符串「test」被寫入到MemoryStream對象中,從GetBuffer返回的緩衝區的長度是256,而不是4,未使用252個字節。要僅獲取緩衝區中的數據,請使用ToArray方法;但是,ToArray會在內存中創建數據的副本。

爲了解決這個問題,你可以調用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 
+1

這個伎倆!謝謝@Steven,我很好奇它是否與擴展的緩衝區大小有關,但不知道爲什麼我之前沒有遇到過這種情況,因爲過去我使用過與其他對象相同的序列化代碼。感謝大家的幫助。 – ewitkows