2010-11-04 82 views
1

这种情况有时只会发生,但会使我的文件无法读取。问题是DataContractSerializer在序列化时在XML文件的末尾添加了几个>>>。在尝试反序列化时使它们无用。有没有人有这个问题?例如:Windows Phone 7中的DataContractSerializer问题

<SomeObject xmlns="someNamespace"> 
</SomeObject>>> 

谢谢。

编辑:

其实也没什么,这不是问题。该文件是罚款这个时候,这是什么样子:

<FavoriteClubManager xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/TicketingWP7.Preferences"> 
<FavoriteClubs xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
    <d2p1:KeyValueOfstringboolean> 
    <d2p1:Key>XXX</d2p1:Key> 
    <d2p1:Value>true</d2p1:Value> 
    </d2p1:KeyValueOfstringboolean> 
</FavoriteClubs> 
</FavoriteClubManager> 

这是尝试反序列化它,当我得到的错误:

“有反序列化类型TicketingWP7的对象错误。偏好.FavoriteClubManager。根元素缺失。“

但我没有看到任何文件错误。

代码

节能:

using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication()) 
{ 
    try 
    { 
     using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(_fileName, FileMode.Create, file)) 
     { 
      DataContractSerializer serializer = new DataContractSerializer(typeof(FavoriteClubManager)); 

      serializer.WriteObject(stream, this); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("There was an error saving your favorite clubs. " + ex.Message); 
    } 
} 

加载:

using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication()) 
{ 
    if (file.FileExists(_fileName)) 
    { 
     try 
     { 
      using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(_fileName, FileMode.Open, file)) 
      { 
       DataContractSerializer serializer = new DataContractSerializer(typeof(FavoriteClubManager)); 

       FavoriteClubManager temp = serializer.ReadObject(stream) as FavoriteClubManager; 

       stream.Close(); 
      } 

      _isLoaded = true; 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("There was an error loading your favorite clubs. " + ex.Message); 
     } 
    } 
} 
+0

ehm和代码? – 2010-11-04 00:44:37

回答

0

解决了它。几乎被骗了。我基本上用XDocument读取XML文档,使用XDocument.CreateReader()获取读者,并将读取器传递给DataContractSerializer。这个伎俩,我知道它不是很优雅,但它是一个解决方案。希望将来我会提出一个更好的解决方案。现在,这里是代码:

private bool Load() 
{ 
    if (!_isLoaded) 
    { 
     using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication()) 
     { 
      if (file.FileExists(_fileName)) 
      { 
       string text = string.Empty; 

       try 
       { 
        using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(_fileName, FileMode.Open, file)) 
        { 
         if (stream.Length > 0) 
         { 
          XDocument document = GetXDocument(stream); 

          DataContractSerializer serializer = new DataContractSerializer(typeof(ClubManager)); 

          ClubManager temp = serializer.ReadObject(document.CreateReader()) as ClubManager; 

          stream.Close(); 
         } 
        } 

        _isLoaded = true; 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show("There was an error loading your favorite clubs. " + ex.Message); 
       } 
      } 
     } 
    } 

    return _isLoaded; 
} 

private XDocument GetXDocument(IsolatedStorageFileStream stream) 
{ 
    // read the file to find errors 
    string documentText = ReadBytes(stream); 

    return XDocument.Parse(documentText); 
} 

private static string ReadBytes(IsolatedStorageFileStream stream) 
{ 
    byte[] buffer = new byte[stream.Length]; 

    stream.Read(buffer, 0, buffer.Length); 

    string normal = string.Empty; 
    string hex = BitConverter.ToString(buffer).Replace("-", ""); 

    while (hex.Length > 0) 
    { 
     // Use ToChar() to convert each ASCII value (two hex digits) to the actual character 
     normal += System.Convert.ToChar(System.Convert.ToUInt32(hex.Substring(0, 2), 16)).ToString(); 
     // Remove from the hex object the converted value 
     hex = hex.Substring(2, hex.Length - 2); 
    } 

    return normal; 
} 

谢谢!

4

是这个问题其实是:

  1. 您序列化对象一次,然后将其保存到孤立存储。
  2. 您从独立存储中读取对象并将其反序列化。
  3. 然后,您更新对象并对其进行重新串行化,然后再次保存。
  4. 您从独立存储中读取它,并且由于多余的字符而无法反序列化它。

如果这是重新创建问题的流程,我怀疑后续保存的seializations是一个稍小的对象,因此创建一个比先前写入的序列化字符串更小的字符串。
当更新的字符串被保存时,它被写在先前保存的字符串的顶部,旧字符串的末尾仍然保留。

解决方法是确保在保存新内容之前删除现有文件或删除其内容。

我以前有类似的问题,这是一个痛苦发现。

顺便说一句。您可能还想重新考虑您的序列化策略的性能。请参阅this blog post by Kevin Marshall了解更多信息。

+0

感谢您的建议。我想到了,所以我决定去做。每次保存之前,文件都会被删除,而额外的>>字符问题已经消失。但是我仍然有反序列化问题,即使第一个问题不再是问题。我一定会看看你建议的序列化策略。 – Carlo 2010-11-04 17:27:28