代码之家  ›  专栏  ›  技术社区  ›  Carlo

Windows Phone 7中的DataContractSerializer问题

  •  1
  • Carlo  · 技术社区  · 14 年前

    <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>
    

    这就是我在反序列化时遇到的错误:

    但我看文件没什么问题。

    保存:

    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);
            }
        }
    }
    
    2 回复  |  直到 14 年前
        1
  •  4
  •   Matt Lacey    14 年前

    问题在于:

    1. 将对象序列化一次,然后将其保存到独立存储。
    2. 从独立存储中读取对象并将其反序列化。
    3. 您从独立存储中读取它,但由于额外的字符,无法对其进行反序列化。

    如果这是重新创建问题的流程,我怀疑随后保存的seialization是一个稍小的对象,因此创建一个序列化字符串,该字符串比之前编写的字符串小。
    当后面的字符串被保存时,它被写在先前保存的字符串的顶部,而旧字符串的末端仍然留在那里。

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

    我以前也有过类似的问题,很难发现。

    顺便说一下,您可能还想重新考虑有关性能的序列化策略。看一看 this blog post by Kevin Marshall 更多信息。

        2
  •  0
  •   Carlo    14 年前

    解决了。在这件事上作弊了。我基本上是用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;
    }
    

    谢谢!