2010-10-20 39 views
3

我正在處理OnNavigatedFrom和To事件中的WP7應用程序的當前狀態,以便如果應用程序被邏輯刪除或者它們導航到不同的頁面,它會將狀態保存到內置的PhoneApplicationService州。如何在邏輯刪除WP7應用程序中調試序列化錯誤

我有一個簡單的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」 的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上拋出了一個更有意義的錯誤。我仍然想知道是否有任何簡單的方法來捕獲此信息...

+0

很難說出與標準導航相比,墓碑上有什麼不同但沒有可行的示例。有各種各樣的原因,該對象可能處於不同的狀態,這意味着能夠正確序列化。 – 2010-10-20 08:21:45

回答

3

羅德尼

我的理解是,當你把一個對象在這兩個國家字典(一關的PhoneApplicationPage和其他關閉PhoneApplicationServices的),它不會立即序列化或反序列化的一個。

如果您使用Page.State存儲數據,它將在離開頁面時序列化狀態包,並在返回頁面時反序列化(而不是在添加或讀取狀態包中的對象時)。

如果您使用PhoneApplicationService.State,則在重新激活應用程序時的邏輯刪除和反序列化時會發生序列化(儘管我不確定它是否與PhoneApplicationService.Activated事件綁定)。

Page.State不允許在頁面之間共享數據。保存到PhoneApplicationService.State確實允許您這樣做。

IsolatedStorage.AppSettings似乎在默默地處理反序列化問題,所以我不確定這是什麼時候發生的。然而,序列化在您調用Save()時發生。

James

2

那麼,你的ViewModel如何表達它的序列化方式?我個人傾向於試圖避開潛在錯綜複雜的序列化:一個相當簡單的選擇是讓您的ViewModel能夠將其自身顯式轉換爲/從XML中自動轉換,然後自己手動執行該步驟,從而保存XDocument(或其字符串表示形式)在應用程序狀態。這種方式很容易調試序列化步驟,看到正在生成的XML等。

當然,這裏使用XML是偶然的 - 如果您可以輕鬆地將所有內容都放入CSV字符串中,那也可以。任何您可以輕鬆檢查之前的序列化格式處於應用狀態之前。我認識到這是側面推進「自動」序列化的一些假設的好處,但我已經遇到了足夠難以診斷的問題與任意對象的自動序列化,我不認爲這些好處超過了缺點。

+0

感謝喬恩,目前我沒有對它做任何事情 - 我感到困惑的是它離開頁面時的工作方式,但不是當墓碑時 - 這不能證明類是可序列化的嗎?它必須在停用時做一些不同的事情。堆棧跟蹤對你來說意味着什麼?我搜索了幾個不同的部分 - 我真的不知道從哪裏開始尋找。也許另一個問題是 - 我如何從這種自動化的抽樣中排除部分課程?我可以嘗試通過消除的過程找到它。 – Rodney 2010-10-20 07:52:05

+0

您可以發佈您的TournamentViewModel類定義嗎? – indyfromoz 2010-10-20 08:47:39

+0

謝謝,我發現了錯誤 - 我使用MVVM技術在VM中創建ApplicationBar,然後綁定到它(因爲您無法綁定到視圖中的AppBar)。這導致了問題(我通過消除過程發現),所以我用[IgnoreDataMember]標記了它,並且它通過了這個問題。我的下一個問題是VM現在繼承了MVVMLight ViewModelBase,它沒有公共無參數的構造函數,因此序列化失敗! http://stackoverflow.com/questions/3976170/issue-with-mvvmlight-viewmodelbase-public-parameterless-constructor-in-inherited – Rodney 2010-10-20 09:02:08