Bug 32116 - System.Runtime.Serialization.SerializationException when access Application.Properties on Windows
Summary: System.Runtime.Serialization.SerializationException when access Application.P...
Status: RESOLVED FIXED
Alias: None
Product: Forms
Classification: Xamarin
Component: Windows ()
Version: 1.4.3
Hardware: PC Windows
: High normal
Target Milestone: ---
Assignee: Jimmy [MSFT]
URL:
Depends on:
Blocks:
 
Reported: 2015-07-19 11:44 UTC by John Hardman
Modified: 2017-08-16 23:11 UTC (History)
10 users (show)

Tags: Windows Exception SerializationException Properties DataLoss uwp fr
Is this bug a regression?: ---
Last known good build:


Attachments
repro project (229.83 KB, application/x-zip-compressed)
2017-07-06 17:42 UTC, Jimmy [MSFT]
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description John Hardman 2015-07-19 11:44:05 UTC
Running a Windows build of XF app on a physical Windows box, suddenly started getting System.Runtime.Serialization.SerializationException when trying to access the Application Properties. This is in an app that has successfully done this hundreds of times, including many times on Winodws. It would seem that somehow the persisted Application Properties got corrupted. The only way I could find of overcoming this was to uninstall the app and re-install it, resulting in loss of all persisted properties.

The detail of the exception is copied below. My educated guess is that there is a threading issue in the saving of Properties within the XF core, but that is just an educated guess.

The big issue with this is that the only method of recovery identified results in the user losing any data stored in Application Properties - a quick way of earning bad reviews and losing customers. Two things are required - (1) a fix that prevents the corruption in the first place, and (2) some method of trying to rescue any properties.

As this involves data loss, please treat this as Critical.


System.AggregateException was unhandled by user code
  HResult=-2146233088
  Message=One or more errors occurred.
  Source=mscorlib
  StackTrace:
       at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
       at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
       at System.Threading.Tasks.Task`1.get_Result()
       at Xamarin.Forms.Application.get_Properties()
       at MarvinPrototype.App..ctor()
       at MyAppName.StoreAppWindows.MainPage..ctor()
       at MyAppName.StoreAppWindows.MyAppName_StoreAppWindows_XamlTypeInfo.XamlTypeInfoProvider.Activate_4_MainPage()
       at MyAppName.StoreAppWindows.MyAppName_StoreAppWindows_XamlTypeInfo.XamlUserType.ActivateInstance()
  InnerException: System.Runtime.Serialization.SerializationException
       HResult=-2146233076
       Message=There was an error deserializing the object of type System.Collections.Generic.IDictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]. The data at the root level is invalid. Line 1, position 1.
       Source=System.Runtime.Serialization
       StackTrace:
            at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
            at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader reader)
            at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(Stream stream)
            at Xamarin.Forms.Platform.WinRT.WindowsSerializer.<DeserializePropertiesAsync>d__0.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
            at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
            at Xamarin.Forms.Application.<GetPropertiesAsync>d__c.MoveNext()
       InnerException: System.Xml.XmlException
            HResult=-2146232000
            Message=The data at the root level is invalid. Line 1, position 1.
            Source=System.Runtime.Serialization
            LineNumber=0
            LinePosition=0
            StackTrace:
                 at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
                 at System.Xml.XmlUTF8TextReader.Read()
                 at System.Xml.XmlBaseReader.IsStartElement()
                 at System.Xml.XmlBaseReader.IsStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
                 at System.Runtime.Serialization.XmlReaderDelegator.IsStartElement(XmlDictionaryString localname, XmlDictionaryString ns)
                 at System.Runtime.Serialization.XmlObjectSerializer.IsRootElement(XmlReaderDelegator reader, DataContract contract, XmlDictionaryString name, XmlDictionaryString ns)
                 at System.Runtime.Serialization.DataContractSerializer.InternalIsStartObject(XmlReaderDelegator reader)
                 at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
                 at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
            InnerException:
Comment 1 Chris King 2015-07-24 13:41:19 UTC
Thanks for taking the time to submit this bug. In order to fix this issue we would need to be able to reproduce it locally. Please attach the application which causes this issue. For faster resolution, please attempt to reduce the reproduction as much as possible. 

Warm regards,
XFT
Comment 2 John Hardman 2015-07-25 09:56:08 UTC
Hi Chris,

I'm afraid I don't have a known way of getting the Application Properties into the state where this symptom occurs.

If there is some way of dumping a binary object containing the entirety of the Application Properties when this does happen (without having to iterate through them and without having to de-reference them), then please let me know and if I see this again I will dump the binary object for you to analyse.

Otherwise, I suspect this is one where Xamarin will need to code-review the APIs provided for Application Properties to try to identify how the properties could be left in an invalid state. My guess is a threading issue based around Application.Current.SavePropertiesAsync(), but it is just an educated guess.

Regards,

John H.
Comment 3 Jason Smith [MSFT] 2016-04-11 08:28:18 UTC
This should be fixed in 2.2.0
Comment 4 Peter Villadsen 2016-10-29 17:32:16 UTC
It is not fixed, or there is a different problem with the Properties dictionary.

I have this problem on the UWP implementations of my Xamarin.Forms project. It has worked many times, but now it does not. There have been no changes made to the source code, or to the version of Xamarin.Forms from the time it worked, till it stopped working.

The aggregate exception contains one inner exception:

{"Error in line 1 position 270. Element 'http://schemas.microsoft.com/2003/10/Serialization/Arrays:Value' contains data of the 'http://schemas.datacontract.org/2004/07/BandAid.Models:TimeFormat' data contract. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'TimeFormat' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer."}

TimeFormat is an enum; in fact all the members in the dictionary are enums. This happens the first time the properties dictionary is accessed in the if statement shown below (in the portable class library):

      if (!App.Current.Properties.ContainsKey(TimeFormatKey))
      {
          // Calculate default value based on user's preferences.
          // TODO: Determine if the phone's settings can be used.
          App.Current.Properties[TimeFormatKey] = TimeFormat.Military;
       }
       return (TimeFormat)App.Current.Properties[TimeFormatKey];
  

Everything works correctly on android and on windows phone and on windows 8.1 targets. I have not tried iPhone.

I am using Xamarin.Forms 2.3.2.127
Comment 5 John Hardman 2017-01-04 23:40:16 UTC
Reopened as two people have reported this recently - Peter Villadsen above, and Bob Howard in the forums at
https://forums.xamarin.com/discussion/85832/i-screwed-up-my-application-current-properties-now-i-am-dead-in-the-water#latest

As per the initial report from July 2015:
"The big issue with this is that the only method of recovery identified results in the user losing any data stored in Application Properties - a quick way of earning bad reviews and losing customers. Two things are required - (1) a fix that prevents the corruption in the first place, and (2) some method of trying to rescue any properties."

Clearly (2) is the first thing that should be done, so that it can be tested.
Comment 6 bob 2017-01-05 14:39:41 UTC
Here is how I reproduced this...

I have a class called NameValue:
` public class NameValue
        {
            public NameValue() { this.name = ""; this.value = ""; }
            public NameValue(string sName, string sValue) { this.name = sName; this.value = sValue; }
            public string name { get; set; }
            public string value { get; set; }
        }`

When attempting to see what I can do with the properties, I was debugging and at a breakpoint, I added a List<NameValue> into the properties:

` Application.Current.Properties["BaseUrl"] = new List<NameValue>()`

It seemingly added it, but after that crashes.
Comment 7 bob 2017-01-05 14:40:30 UTC
I added the above line through the immediate window btw...
Comment 8 bob 2017-01-05 15:26:35 UTC
I have narrowed it down to the C:\Users\<Me>\AppData\Local\Packages\<Guid>\RoamingStatePropertyStore.forms file.  Here are the contents:

<ArrayOfKeyValueOfstringanyType xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <KeyValueOfstringanyType>
    <Key>BaseUrl</Key>
    <Value i:type="a:string" xmlns:a="http://www.w3.org/2001/XMLSchema">https://www.ChartMeds.com/ChartMeds</Value>
  </KeyValueOfstringanyType>
  <KeyValueOfstringanyType>
    <Key>FormBackgroundColor</Key>
    <Value i:type="a:string" xmlns:a="http://www.w3.org/2001/XMLSchema">fff</Value>
  </KeyValueOfstringanyType>
  <KeyValueOfstringanyType>
    <Key>LastServiceCallCheckForPatients</Key>
    <Value i:type="a:ArrayOfGeneralTypeClasses.NameValue" xmlns:a="http://schemas.datacontract.org/2004/07/ChartMedsMobile.Classes">
      <a:GeneralTypeClasses.NameValue>
        <a:name>1</a:name>
        <a:value>2016/12/06 10:36:10</a:value>
      </a:GeneralTypeClasses.NameValue>
    </Value>
  </KeyValueOfstringanyType>
  <KeyValueOfstringanyType>
    <Key>RootUrl</Key>
    <Value i:type="a:string" xmlns:a="http://www.w3.org/2001/XMLSchema">https://www.ChartMeds.com</Value>
  </KeyValueOfstringanyType>
  <KeyValueOfstringanyType>
    <Key>DevUrl</Key>
    <Value i:type="a:string" xmlns:a="http://www.w3.org/2001/XMLSchema">http://192.168.1.5</Value>
  </KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType>
Comment 11 John Hardman 2017-07-04 14:38:45 UTC
Just spotted this on StackOverflow - https://stackoverflow.com/questions/41707988/corrupt-application-current-properties-in-xamarin

Thought it worth mentioning here, as it sounds like the same thing.
Comment 12 Jimmy [MSFT] 2017-07-06 17:42:16 UTC
Created attachment 23359 [details]
repro project

As stated in the Properties Dictionary doc[1], we do not recommend storing non-primitive types such as List<T> or enums in the dictionary because the current serializer might not handle them properly. This seems to be the case in the recent reports of this issue.

If you run the project I've attached on Android and iOS, there doesn't seem to be any issues with the dictionary after storing non-primitives types. However on UWP, doing the same and then restarting the app will cause future attempts to access the dictionary to fail with the exception in comment 4.

I did notice that while this works on Android, there is an exception that gets printed to the debug output[2] from this line[3]. So the serializer _is_ throwing an exception in Android as well, but we are handling it. On UWP, it looks like we only handle a FileNotFoundException[4].

We should add a catch all for other exceptions in the UWP implementation so at least the app doesn't crash so I will still confirm this report. However the recommendation above remains as we still cannot guarantee that the value will be deserialized properly.


[1] https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/application-class/#Properties_Dictionary
[2] https://gist.github.com/jimmgarrido/d7812588529c4bfccd09c177f698568e
[3] https://github.com/xamarin/Xamarin.Forms/blob/2.3.4-2/Xamarin.Forms.Platform.Android/Deserializer.cs#L31
[4] https://github.com/xamarin/Xamarin.Forms/blob/2.3.4-2/Xamarin.Forms.Platform.WinRT/WindowsSerializer.cs#L35
Comment 13 Jimmy [MSFT] 2017-07-06 18:17:03 UTC
https://github.com/xamarin/Xamarin.Forms/pull/1036