MVVMCross - Overriding The Default Plugins

December 25, 2014

Following on from this post I discovered that I did, indeed, have a recursive reference in my game file. After a little searching, I found this excellent article on how to prevent this error, and to make the Json serializer behave rationally.

In MVVMCross, the code to serialize JSON is based on a standard plugin; it looks like this (or at least this is how I am saving my game):



public void Save()
{
    var jsonConv = Mvx.Resolve<IMvxJsonConverter>();            
    string text = jsonConv.SerializeObject(this);
    FileHelper.SaveGameFile(text);
}

The type is registered in App.cs like this:



Mvx.RegisterType<IMvxJsonConverter, MvxJsonConverter>();

What’s the fix?

The above article says the fix is this:



Settings = new JsonSerializerSettings
{
    PreserveReferencesHandling = PreserveReferencesHandling.Objects

(it does go into more detail and I encourage everyone to read it).

So this is a change to MVVM Cross

Might be.

However, you can always use your own Serializer. One of the things that I’ve come to really like about MVVM Cross if that if you don’t like something, just write your own and override that specific thing. I stole this code, verbatim, from MVVM Cross, with the single exception of the one line above:



    public class MyJSonConverter : IMvxJsonConverter
    {
        private static readonly JsonSerializerSettings Settings;

        static KMJSonConverter()
        {
            Settings = new JsonSerializerSettings
            {
                ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize,
                Converters = new List<JsonConverter>
                        {
                            new MvxEnumJsonConverter(),
                        },
                DateFormatHandling = DateFormatHandling.IsoDateFormat,
                PreserveReferencesHandling = PreserveReferencesHandling.Objects
            };
        }

        public T DeserializeObject<T>(string inputText)
        {
            return JsonConvert.DeserializeObject<T>(inputText, Settings);
        }

        public string SerializeObject(object toSerialise)
        {
            return JsonConvert.SerializeObject(toSerialise, Formatting.None, Settings);
        }

        public object DeserializeObject(Type type, string inputText)
        {
            return JsonConvert.DeserializeObject(inputText, type, Settings);
        }
    }

Now, in App.cs, just change how it is registered:



Mvx.RegisterType<IMvxJsonConverter, MyJSonConverter>();
//Mvx.RegisterType<IMvxJsonConverter, MvxJsonConverter>();

Job done. It now works!



Profile picture

A blog about one man's journey through code… and some pictures of the Peak District
Twitter

© Paul Michaels 2024