kdhansen
kdhansen

Reputation: 117

Json-deserialization of List<T> fails: the type requires a JSON array to deserialize correctly

I am working on a Xamarin.Forms app in which I need to cache data when no internet connection is available. I am currently using the built-in Application.Current.Properties persistence mechanism to persist data, which is working just fine. However, for a more complex object, I am failing to deserialize.

I have the following object Model:

public class SPL
{
    public SPL(Point point, Location location)
    {
        Point = point;
        Location = location;
    }

    public Location Location { get; set; }
    public Point Point { get; set; }
}

Where Location have two properties of type double and Point has two properties of type DateTime and type double, respectively.

Through the execution time of the app I continuously persist data in the local cache like so, whenever no internet connection is available

SPL spl = new SPL(point, location);
SPLValues.Add(spl);
var serializedSpl = JsonConvert.SerializeObject(SPLValues);
Application.Current.Properties["splvalues"] = serializedSpl;

Breaking at the last line and inspecting with the debugger reveals the the data is persisted.

When the app goes to sleep I call Current.SavePropertiesAsync();. Upon resuming the app I then try to deserialize the local cache like so

public List<T> GetCache<T>(string key) where T : class
{
    IDictionary<string, object> properties = Application.Current.Properties;
    if (properties.ContainsKey(key))
    {
        var data = JsonConvert.DeserializeObject<List<T>>(key); // Fails here
        return data;
    }
    return new List<T>();
}

Which fails. The exception thrown is

Unhandled Exception: Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: s. Path '', line 0, position 0. occurred

UPDATE

As pointed out by JOSEFtw, I was missing a parameter in my deserialization call, so it now looks like this instead: var data = JsonConvert.DeserializeObject<List<T>>(properties[key]);

After fixing this, I now encounter this error:

Unhandled Exception: Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[CacheDemo.Models.SPL]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'Location', line 1, position 12. occurred

What am I doing wrong?

Upvotes: 0

Views: 619

Answers (2)

kdhansen
kdhansen

Reputation: 117

I have actually solved the issue, but it is not what I expected. I am reluctant to post this as an answer as it does not really tie into the actual error. However, it seemed that the Properties contained an empty Location object (it had no properties) and thus upon deserialization it failed. Which in itself is odd to me, as I would expect it to just return an empty object, then? I can't gather how the Location object was written to disk as being empty, and running .Clear() on Properties did not seem to remove it. What worked was to deploy the app to a physical device, and suddenly the error vanished. Inspecting the Properties cache using the debugger on the physical device revealed that the empty Location object had been removed, and this is why I am assuming that the empty Location object was at fault.

Upvotes: 0

JOSEFtw
JOSEFtw

Reputation: 10091

I think that you should Deserialize

properties[key] 

instead of

key

Like this

var data = JsonConvert.DeserializeObject<List<T>>(properties[key]); 

Upvotes: 1

Related Questions