0

我正在尝试二进制序列化来处理一些复杂的对象。使用 SharpSerializer,序列化工作没有问题,但我不能反序列化。

这是代码片段和堆栈跟踪。

var settings = new SharpSerializerBinarySettings();
settings.IncludeAssemblyVersionInTypeName = true;
settings.IncludeCultureInTypeName = true;
settings.IncludePublicKeyTokenInTypeName = true;
settings.Mode = BinarySerializationMode.Burst;
var serializer = new SharpSerializer(settings);
using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(basePath + "current" + extension, FileMode.Open, isoStore))
{    
    try
    {
        result = serializer.Deserialize(isoStream) as MyObject;
        System.Diagnostics.Debug.WriteLine("loaded from " + basePath + "current" + extension);
     }
     catch (Exception ex)
     {
         System.Diagnostics.Debug.WriteLine(ex.Message);
     }
 }

堆:

  ex {Polenter.Serialization.Core.DeserializingException: An error occured during the deserialization.
   Details are in the inner exception. ---> System.TypeLoadException: Could not load type 'otContent ShowGridLines BackgroundColorARGBOpacity TransformMatrixM11M12M21M22Offs' from assembly 'Polenter.SharpSerializer.Silverlight, Version=2.18.0.0, Culture=neutral, PublicKeyToken=8f4f20011571ee5f'.
   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type)
   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
   at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
   at System.Type.GetType(String typeName, Boolean throwOnError)
   at Polenter.Serialization.Advanced.TypeNameConverter.ConvertToType(String typeName)
   at Polenter.Serialization.Advanced.BurstBinaryReader.ReadType()
   at Polenter.Serialization.Advanced.BinaryPropertyDeserializer.deserialize(Byte elementId, String propertyName, Type expectedType)
   at Polenter.Serialization.Advanced.BinaryPropertyDeserializer.deserialize(Byte elementId, Type expectedType)
   at Polenter.Serialization.Advanced.BinaryPropertyDeserializer.Deserialize()
   at Polenter.Serialization.SharpSerializer.Deserialize(Stream stream)
   --- End of inner exception stack trace ---
   at Polenter.Serialization.SharpSerializer.Deserialize(Stream stream)
   at MyNamespace.DataManager.MyMethod()}   System.Exception {Polenter.Serialization.Core.DeserializingException}

我想反序列化一个复杂的结构,其中有自定义控件的层次结构和大量继承。

这段代码有什么问题?

编辑:序列化代码

var settings = new SharpSerializerBinarySettings();
settings.IncludeAssemblyVersionInTypeName = true;
settings.IncludeCultureInTypeName = true;
settings.IncludePublicKeyTokenInTypeName = true;
settings.Mode = BinarySerializationMode.Burst;
var serializer = new SharpSerializer(settings);   
using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(basePath + "current" + extension, FileMode.Create, isoStore))
{  
    serializer.Serialize(MyObject, isoStream);
    IsolatedStorageSettings.ApplicationSettings["saved"] = true;
    IsolatedStorageSettings.ApplicationSettings.Save();
    System.Diagnostics.Debug.WriteLine("Saved to " + basePath + "current" + extension);
}

我试图序列化/反序列化的对象是这样的:

[DataContract]
public partial class MainObject : UserControl
{
    [IgnoreDataMember]
    private int zIndex = 10;

    [DataMember]
    private Dictionary<BasePlugin, Point> usedPlugins = new Dictionary<BasePlugin, Point>();

    ...methods...
}

其中BasePluginaUserControl是由其他类型扩展的。这是BasePlugin课程

/// <summary>
/// Base class from which every plugin derives
/// </summary>
[DataContract]
public abstract partial class BasePlugin: UserControl
{

    [IgnoreDataMember]
    protected StackPanel settingsPanel;
    public StackPanel SettingsPanel
    {
        get
        {                
            if (settingsPanel == null)
            {
                settingsPanel = buildSettingsPanel();
            }
            return settingsPanel;
        }
    }

    [DataMember]
    protected Color backgroundColor = Color.FromArgb(255, 255, 255, 255);
    public Color BackgroundColor
    {
        get { return backgroundColor; }
        set { backgroundColor = value; }
    }

    [DataMember]
    protected Color foregroundColor = Color.FromArgb(255, 0, 0, 0);
    public Color ForegroundColor
    {
        get { return foregroundColor; }
        set { foregroundColor = value; }
    }

    [DataMember]
    protected string pluginName;
    public string PluginName
    {
        get { return pluginName; }
        protected set { pluginName = value; }
    }

    [DataMember]
    protected string pluginDescription;
    public string PluginDescription
    {
        get { return pluginDescription; }
        protected set { pluginDescription = value; }
    }

    [DataMember]
    protected Category pluginCategory;
    public Category PluginCategory
    {
        get { return pluginCategory; }
        protected set { pluginCategory = value; }
    }

    ...methods...
}

就像附带信息一样,运行昨天的相同代码现在会导致此消息:

  Message "Error during creating an object. Please check if the type \"System.Windows.Markup.XmlLanguage, System.Windows, Version=2.0.6.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e\" has public parameterless constructor, or if the settings IncludeAssemblyVersionInTypeName, IncludeCultureInTypeName, IncludePublicKeyTokenInTypeName are set to true. Details are in the inner exception."  string
4

1 回答 1

1

你手上有一个非常复杂的对象,你想(反)序列化。从您的角度来看,这似乎很简单,但您继承自一个已经很复杂的对象 ( UserControl)。并且 SharpSerializer 默认情况下将序列化所有公共属性,无论如何。这很可能会导致您遇到的问题。

可能的解决方案:

  • 尝试(反)序列化用于序列化的对象中所需的信息/属性。然后编写一些工具来在您的序列化对象和您的业务对象(您在此处介绍的对象)之间进行转换。
  • 尝试更多地配置 SharpSeralizer,以便您只存储您需要的属性(并且也可以正确序列化)并且开箱即用。
于 2013-09-15T10:15:28.470 回答