如何在逻辑删除的WP7应用程序中调试序列化错误

时间:2010-10-20 07:35:49

标签: serialization silverlight-3.0 windows-phone-7

我在OnNavigatedFrom和To事件中处理我的WP7应用程序的当前状态,这样如果应用程序被逻辑删除或者他们导航到另一个页面,它会将状态保存到内置的PhoneApplicationService状态。

我有一个简单的ViewModel which I dump to the state让生活更轻松。导航到我的应用程序中的不同页面时,状态存储正常并恢复正常(即,我认为此时正在序列化)。但是,当我 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:“无法计算表达式”

堆栈跟踪:

   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]标记了它,它现在在different problem上抛出了更有意义的错误。我仍然想知道是否有任何简单的方法来捕捉这些信息...

2 个答案:

答案 0 :(得分:3)

罗德尼,

我的理解是当你将一个对象放在两个State Dictionaries之一(一个关闭PhoneApplicationPage而另一个关闭PhoneApplicationServices)时,它不会立即序列化或反序列化。

如果您使用Page.State存储数据,它会在您离开页面时序列化您的状态包,并在您返回页面时反序列化(而不是在您从状态包中添加或读取对象时)。< / p>

如果使用PhoneApplicationService.State,则在重新激活应用程序时进行逻辑删除和反序列化时会发生序列化(尽管我不确定这是否与PhoneApplicationService.Activated事件有关)。

顺便说一下,Page.State不允许在页面之间共享数据。保存到PhoneApplicationService.State允许您这样做。

IsolatedStorage.AppSettings似乎无声地处理反序列化问题,所以我不确定何时会发生这种情况。但是,当您调用Save()时会发生序列化。

詹姆斯

答案 1 :(得分:2)

那么,你的ViewModel如何表达它可序列化的方式?我个人倾向于避免潜在复杂的序列化:一个相当简单的选择是让ViewModel能够显式地将自身转换为XML,然后自己手动执行该步骤,保存XDocument(或其字符串表示形式)处于应用程序状态。这样就可以轻松调试序列化步骤,查看生成的确切XML等。

当然,这里使用XML是偶然的 - 如果你可以轻松地将所有内容放在CSV字符串中,那也没关系。在进入应用程序状态之前,您可以根据序列化表单轻松检查的任何内容。

我意识到这是“自动”序列化的一些所谓的好处,但是我遇到了任意对象的自动序列化的足够难以诊断的问题,我认为这些问题不会超过缺点。