Reputation: 2852
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:
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.
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;
...
}
Upvotes: 2
Views: 522
Reputation: 126
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[]>();
Upvotes: 3