2009-07-22 39 views
4

我正在序列化一个包含String属性中的HTML数据的对象。包含无效字符的对象的XML序列化

Dim Formatter As New Xml.Serialization.XmlSerializer(GetType(MyObject)) 
Dim fs As New FileStream(FilePath, FileMode.Create) 
Formatter.Serialize(fs, Ob) 
fs.Close() 

但是,当我在看XML回对象:

Dim Formatter As New Xml.Serialization.XmlSerializer(GetType(MyObject)) 
Dim fs As New FileStream(FilePath, FileMode.Open) 
Dim Ob = CType(Formatter.Deserialize(fs), MyObject) 
fs.Close() 

我得到这个错误:

"'', hexadecimal value 0x14, is an invalid character. Line 395, position 22." 

不应该.NET防止这种错误的,转义无效字符?

这里发生了什么,我该如何解决?

回答

2

它应该真的在序列化步骤失败,因为0x14 is an invalid value for XML无法转义它,即使使用&#x14也无法逃避它,因为它被排除为XML模型中的有效字符。序列化程序让我们感到惊讶,因为它使得序列化程序不合规。

是否可以在序列化之前从字符串中删除无效字符?为了什么目的,你在HTML中有一个0x14

或者,您是否可以使用一种编码进行编写,然后使用另一种编码进行阅读?

+0

嗯,我已经走了这个解决方案。在序列化之前,我从字符串中删除了无效字符。但是,我仍然不明白为什么不XmlSerializer反序列化已序列化的对象。 – InfoStatus 2009-07-22 18:18:10

+0

您的状态良好,除非无效字符非常重要。 – 2009-07-22 18:36:51

+1

我在这里发现了这个问题的更全面的描述:http://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/ – Derrick 2011-01-10 15:19:50

0

我会怎样exepct .NET来处理这个问题,但你也可以看看XmlSerializer类和XmlReaderSettings(见下面的示例通用方法):

public static T Deserialize<T>(string xml) 
{ 
    var xmlReaderSettings = new XmlReaderSettings() 
           { 
            ConformanceLevel = ConformanceLevel.Fragment, 
            ValidationType = ValidationType.None 
           }; 

    XmlReader xmlReader = XmlTextReader.Create(new StringReader(xml), xmlReaderSettings); 
    XmlSerializer xs = new XmlSerializer(typeof(T), ""); 

    return (T)xs.Deserialize(xmlReader); 
} 

我还要检查是否有没有编码(统一,UTF8等)问题。十六进制值0x14不是您期望的XML中的字符:)

1

您应该真正发布您尝试序列化和反序列化的类的代码。同时,我会猜测。

很可能,无效字符位于string类型的字段或属性中。您需要序列化的字节数组,假设你不能避免该角色目前在所有:

[XmlRoot("root")] 
public class HasBase64Content 
{ 
    internal HasBase64Content() 
    { 
    } 

    [XmlIgnore] 
    public string Content { get; set; } 

    [XmlElement] 
    public byte[] Base64Content 
    { 
     get 
     { 
      return System.Text.Encoding.UTF8.GetBytes(Content); 
     } 
     set 
     { 
      if (value == null) 
      { 
       Content = null; 
       return; 
      } 

      Content = System.Text.Encoding.UTF8.GetString(value); 
     } 
    } 
} 

这将产生XML这样的:

<?xml version="1.0" encoding="utf-8"?> 
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Base64Content>AAECAwQFFA==</Base64Content> 
</root> 

我看你可能更喜欢VB.NET:

''# Prettify doesn't like attributes as the first item in a VB code block, so this comment is here so that it looks right on StackOverflow. 
<XmlRoot("root")> _ 
Public Class HasBase64Content 

    Private _content As String 
    <XmlIgnore()> _ 
    Public Property Content() As String 
     Get 
      Return _content 
     End Get 
     Set(ByVal value As String) 
      _content = value 
     End Set 
    End Property 

    <XmlElement()> _ 
    Public Property Base64Content() As Byte() 
     Get 
      Return System.Text.Encoding.UTF8.GetBytes(Content) 
     End Get 
     Set(ByVal value As Byte()) 
      If Value Is Nothing Then 
       Content = Nothing 
       Return 
      End If 
      Content = System.Text.Encoding.UTF8.GetString(Value) 
     End Set 
    End Property 
End Class 
6

我集T他将XmlReaderSettings属性的CheckCharacters设置为false。 我只会建议这样做,如果你已经通过XmlSerializer自己序列化数据。如果来自未知来源,那么这不是一个好主意。

public static T Deserialize<T>(string xml) 
{ 
    var xmlReaderSettings = new XmlReaderSettings() { CheckCharacters = false }; 

    XmlReader xmlReader = XmlTextReader.Create(new StringReader(xml), xmlReaderSettings); 
    XmlSerializer xs = new XmlSerializer(typeof(T)); 

    return (T)xs.Deserialize(xmlReader); 
} 
相关问题