Как отладить ошибку сериализации в захороненном приложении WP7 - PullRequest
3 голосов
/ 20 октября 2010

Я обрабатываю текущее состояние моего приложения WP7 в событиях OnNavigatedFrom и To, так что, если приложение захоронено, или они переходят на другую страницу, оно сохраняет состояние во встроенном состоянии PhoneApplicationService.

Iу меня есть ViewModel, который я дам в состояние , чтобы облегчить жизнь.При переходе на другую страницу в моем приложении состояние сохраняется в порядке и восстанавливается в порядке (т. Е. Я предполагаю, что на этом этапе он сериализуется).Однако, когда я tombstone приложение (то есть кнопка Пуск), я получаю необработанную ошибку с сериализацией, и трассировка стека не дает мне никаких подсказок относительно того, почему это терпит неудачу.

Я попытался обернуть фактический вызов в блок try catch, чтобы попытаться увидеть, что не так, но это не помогает - это то, что среда выполнения делает разные вещи при захоронении моего объекта, чем когда он просто хранитэто между страницами.

Вот мой код:

protected override void OnNavigatedFrom(NavigationEventArgs args)
{
   appService.State["TournamentViewModel"] = tournamentViewModel;
   base.OnNavigatedFrom(args);
}

protected override void OnNavigatedTo(NavigationEventArgs args)
{
    if (appService.State.ContainsKey("TournamentViewModel"))
    {
        tournamentViewModel = (TournamentViewModel)appService.State["TournamentViewModel"];
    }
    base.OnNavigatedTo(args);
}

Это ошибка, которая генерируется - я действительно не могу понять, где проблема - как я могу отладить это лучше?

Информация об исключении : Сообщение: «SecurityException» InnerException: «Не удалось оценить выражение»

StackTrace:

   at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateGetOnlyCollectionDataContract(Int32 id, RuntimeTypeHandle typeHandle, Type type)
   at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetGetOnlyCollectionDataContractSkipValidation(Int32 id, RuntimeTypeHandle typeHandle, Type type)
   at System.Runtime.Serialization.DataContract.GetGetOnlyCollectionDataContractSkipValidation(Int32 id, RuntimeTypeHandle typeHandle, Type type)
   at System.Runtime.Serialization.XmlObjectSerializerContext.GetDataContractSkipValidation(Int32 typeId, RuntimeTypeHandle typeHandle, Type type)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at System.Runtime.Serialization.XmlFormatWriter.InternalSerialize(MethodInfo methodInfo, Object memberValue, Type memberType, Boolean writeXsiType, XmlObjectSerializerWriteContext context, XmlWriterDelegator xmlWriter)
   at System.Runtime.Serialization.XmlFormatWriter.WriteValue(Type memberType, Object memberValue, Boolean writeXsiType, XmlObjectSerializerWriteContext context, XmlWriterDelegator xmlWriter)
   at System.Runtime.Serialization.XmlFormatWriter.WriteMember(SerializingObject serObj, Int32 memberIndex, ClassDataContract derivedMostClassContract)
   at System.Runtime.Serialization.XmlFormatWriter.WriteClass(CallStackElement`1 callStackElement)
   at System.Runtime.Serialization.XmlFormatWriter.Serialize(XmlObjectSerializerWriteContext context)
   at System.Runtime.Serialization.XmlFormatWriter.InitializeCallStack(XmlWriterDelegator xmlWriterDel, Object obj, XmlObjectSerializerWriteContext writeContext, DataContract contract)
   at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph)
   at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph)
   at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph)
   at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter writer, Object graph)
   at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(Stream stream, Object graph)
   at Microsoft.Phone.Shell.StreamPersister.Serialize(IDictionary`2 dictionary, IEnumerable`1 knownTypes)
   at Microsoft.Phone.Shell.StreamPersister.Save(ShellPageManager shellPageManager, String key, IDictionary`2 dictionary, IEnumerable`1 knownTypes)
   at Microsoft.Phone.Shell.PhoneApplicationService.FireDeactivated()
   at Microsoft.Phone.Execution.NativeEmInterop.FireOnPause()

Обновление: пробными ошибка я обнаружил, что проблема в AppBar, который не представляется сериализуемым.Я пометил его [IgnoreDataMember], и теперь он выдает более значимую ошибку при другой проблеме .Я все еще хотел бы знать, есть ли какие-нибудь легкие способы поймать эту информацию ...

Ответы [ 2 ]

3 голосов
/ 20 октября 2010

Родни,

Насколько я понимаю, когда вы помещаете объект в один из двух словарей состояний (один из PhoneApplicationPage, а другой из PhoneApplicationServices), он не сразу сериализуется или десериализуется.

Если вы используете Page.State для хранения данных, он сериализует ваш пакет состояний, когда вы покидаете страницу, и десериализуется, когда вы возвращаетесь на страницу (а не когда вы добавляете или читаете объект из пакета состояний).

Если вы используете PhoneApplicationService.State, сериализация происходит при захоронении и десериализации при повторной активации приложения (хотя я не уверен, связано ли это с событием PhoneApplicationService.Activation или нет).

Page.State, кстати, не позволяет обмениваться данными между страницами.Сохранение в PhoneApplicationService.State позволяет вам сделать это.

IsolatedStorage.AppSettings, кажется, решает проблемы десериализации в молчании, поэтому я не уверен, когда это произойдет.Однако при вызове Save () происходит сериализация.

James

2 голосов
/ 20 октября 2010

Ну, как ваш ViewModel выражает способ его сериализации? Лично я стараюсь избегать потенциально запутанной сериализации: один довольно простой вариант - дать вашей ViewModel возможность явного преобразования себя в / из XML, а затем выполнить этот шаг вручную, сохранив XDocument (или его строковое представление) в состоянии приложения. Таким образом, легко отладить этап сериализации, увидеть точный генерируемый XML и т. Д.

Конечно, использование XML здесь является случайным - если вы можете легко поместить все в строку CSV, это тоже будет хорошо. Все, что вы можете легко проверить с помощью сериализованной формы перед тем, как перейдет в состояние приложения.

Я понимаю, что это обходит некоторые из предполагаемых преимуществ «автоматической» сериализации, но я столкнулся с достаточно сложными для диагностики проблемами с автоматической сериализацией произвольных объектов, которые, я думаю, не перевешивают преимущества недостатки.

...