2

I've run into a confusing problem that i cannot seem to solve.

I'm using Json.Net and i've written a custom Json converter to handle a special case in my application. The issue i've run into is in the deserialize or ReadJson method which is throwing an error when it tires to convert a JSON array into an array of strings:

enter image description here

The exact text of the error is: Unexpected token while deserializing object: PropertyName. Path 'RootPages', line 1, position 13.

As you can see from the inspector, the JProperty it is trying to deserialize (RootPages) has been parsed correctly and is valid JSON. enter image description here

So i'm not entirely sure what is going on here, any enlightenment would be greatly appreciated..

If relevant, the original JSON string is as follows:

{
  "RootPages": [
    "TestItem1",
    "TestItem2"
  ],
  "Name": "root"
}

EDIT-CODE:

ReadJson Method:

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        if (PartialChildPageSerialization) {
            var jsonObject = JObject.Load(reader);
            var properties = jsonObject.Properties().ToList();

            foreach (var property in objectType.GetProperties()) {
                var type = property.PropertyType;
                object value = null;

                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ChildPageCollection<>)) {
                    var collection = Activator.CreateInstance(type);
                    var deserializedValue = properties.First(p => p.Name == property.Name).ToObject<string[]>();
                    type.GetMethod("PolulateFromSerializer").Invoke(collection, new object[] {deserializedValue});
                    value = collection;
                }
                else {
                    value = properties.First(p => p.Name == property.Name).ToObject(type);
                }

                property.SetValue(existingValue, value);
            }

            return existingValue;
        }

        return serializer.Deserialize(reader, objectType);
    }

Snippet of the interesting part of ChildPageCollection:

public class ChildPageCollection<T> : IList<T> where T : DataPage
{
    public string[] GetNames() => _internalNameList.ToArray();

    internal void PolulateFromSerializer(string[] names) {
        this.Clear();
        _internalNameList.AddRange(names);
        _hasFullList = false;
    }

    private void CheckFullList() {
        if(!_hasFullList)
            throw new InvalidOperationException("Collection has not been fully loaded, and full list is not avialable.");
    }

    private readonly List<T> _internalList = new List<T>();
    private readonly List<string> _internalNameList = new List<string>();
    private bool _hasFullList = true;

    ...
}
1
  • Sure, i thought that may be an issue, but i figured i'd port it first and see! Commented Dec 23, 2017 at 17:30

1 Answer 1

3

I expect this is because the first property is an object with a property called 'RootPages' which is a string[].

Unfortunately from the looks of your screenshots you are trying to turn an object into a string array.

This should work in the example you've given:

properties.First(p => p.Name == property.Name).Select(o => o.Children().Values<string>()).First().ToArray();

In place of:

properties.First(p => p.Name == property.Name).ToObject<string[]>();
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Looks like that did the trick. Your answer did indeed work, however i did also notice after reading your explanation all i had to add was a .Value before the .ToObject and the library was able to work out that conversion for me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.