Loading an Enumeration from Application.Current.Properties Causes Exception

Nathan Sokalski 4,111 Reputation points
2021-02-10T22:57:14.08+00:00

I have a Xamarin.Forms app with an enum defined as follows:

[System.Flags] public enum SettingsEnum  

I need to save/load a variable of this type to Application.Current.Properties. As we all know, the default underlying type of enum is int, which is a primitive. I have no problem when saving the value, but when I try to read it, I get the following Exception:

Xamarin.Forms PropertyStore: Exception while reading Application properties: System.Runtime.Serialization.SerializationException: Element 'http://schemas.microsoft.com/2003/10/Serialization/Arrays:Value' contains data of the 'http://schemas.datacontract.org/2004/07/PointTracker_Forms:SettingsEnum' data contract. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'SettingsEnum' 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.

I looked at the KnownTypeAttribute at:

https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.knowntypeattribute?view=net-5.0

But it says it can only be used for classes & structs. I have considered manually converting it to/from an int when saving or loading it, but this seems like it should be unnecessary. I also noticed that the Exception message shown above is able to recognize what type it is (not that it matters, since Properties contains Object(s), so I would be required to convert it regardless). What should I do to store an enum value in Application.Current.Properties? Is there any option other than manual conversion to/from int? Thanks.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,366 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 77,256 Reputation points Microsoft Vendor
    2021-02-11T03:05:51.717+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    Let us to reproduce this issue.

    First of all, you create a enum type, for testing, I add three value in it like following code.

       [System.Flags]  
           public enum SettingsEnum  
           {  
         
               Low=1,  
               Medium=2,  
               High=3  
           }  
    

    Then I save value in the App's constructor.

       public App()  
               {  
                   InitializeComponent();  
                   Application.Current.Properties["id"] = (int)SettingsEnum.Low;  
                   MainPage = new MainPage();  
                     
               }  
    

    In the MainPage, we can get the saved value.

       public MainPage()  
               {  
                   InitializeComponent();  
         
                   if (Application.Current.Properties.ContainsKey("id"))  
                   {  
                       var id = Application.Current.Properties["id"];  
         
                       SettingsEnum foo = (SettingsEnum)id;  
                       // do something with id  
                   }  
               }  
    

    Here is running screenshot, I can get the value.

    66791-image.png

    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


1 additional answer

Sort by: Most helpful
  1. John Hardman 261 Reputation points
    2021-02-11T12:54:28.447+00:00

    You should do the conversion manually. It's debatable whether it's best to persist the value as an int or a string.

    If you want to use a string, see:
    https://learn.microsoft.com/en-us/dotnet/api/system.enum.tostring?view=net-5.0
    https://learn.microsoft.com/en-us/dotnet/api/system.enum.parse?view=net-5.0

    The reason that it's best to do the conversion manually, and why you might want to consider using strings, is what happens if the enum in C# is modified in a later release of the app, after data has already been persisted on a device. If you're the only person working on the codebase, you might just put a comment in the code to remind you never to change the values of the existing elements of the enum. In a team environment, you could do the same - just putting a comment in, but knowing how rarely some developers read comments there is a risk that the comment will be ignored. Should that happen, errors will occur when persisted values are read back in after updating the app. Regardless, you'll want to handle unrecognised values, which just doing a cast won't do for you.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.