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

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

  •  3
  • Rodney  · 技术社区  · 14 年前

    我正在OnNavigatedFrom和To事件中处理我的WP7应用程序的当前状态,以便如果该应用程序被删除或导航到其他页面,它会将状态保存到内置的PhoneApplicationService状态。

    我有一个简单的 ViewModel which I dump to the state 让生活更轻松。当导航到我的应用程序中的另一个页面时,状态存储良好并恢复良好(即,我假设此时它正在序列化)。但是,当我 应用程序(即“开始”按钮)序列化时出现未处理的错误,stacktrace没有提供任何有关失败原因的线索。

    我已经尝试将实际调用包装到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”

    堆栈跟踪:

       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 回复  |  直到 7 年前
        1
  •  3
  •   James Ashley    14 年前

    罗德尼,

    我的理解是,当您将一个对象放入两个状态字典之一(一个离开PhoneApplicationPage,另一个离开PhoneApplicationServices)时,它不会立即序列化或反序列化。

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

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

    詹姆斯

        2
  •  2
  •   Jon Skeet    14 年前

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

    之前 正在进入应用程序状态。

    我意识到这是在回避“自动”序列化的一些假定好处,但我遇到了很难诊断的问题,自动序列化的任意对象,我不认为好处大于缺点。