DeserializingException с использованием SharpSerializer
Я пытаюсь двоичной сериализации для работы с некоторыми сложными объектами. Используя 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...
}
где BasePlugin
это UserControl
который расширяется другими типами. Вот 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
1 ответ
У вас в руках очень сложный сложный объект, который вы хотите (де) сериализовать. Это кажется простым с вашей точки зрения, но вы наследуете от уже сложного объекта (UserControl
). А SharpSerializer по умолчанию будет сериализовать все открытые свойства, несмотря ни на что. И это, скорее всего, приводит к проблемам, которые у вас есть.
Возможные решения:
- Попробуйте (де) сериализовать только ту информацию / свойства, которые вам нужны в объекте, который предназначен только для сериализации. Затем напишите некоторое средство, которое преобразует между вашими объектами сериализации и вашими бизнес-объектами (теми, которые вы представили здесь)
- Попробуйте настроить SharpSeralizer больше, чтобы хранить только те свойства, которые вам нужны (а также могут правильно сериализоваться) и которые работают из коробки.