Newtonsoft JSON.NET解析为自定义键/值对对象的数组

我在解析给定的JSON数据时遇到了一个奇怪的问题。我有这个JSON结构:

{"value":[

{"street":"Karlova 25"},

{"city":"Prague"},

{"gpsLat":"50.1571"},

{"gpsLon":"15.0482"}

]}

如何使用Newtonsoft JSON.NET库解析此结构?我尝试使用自己的JsonConverter类:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer){

JArray jarray = (JArray)((JTokenReader)reader).CurrentToken;

List<AddressValue> values = new List<AddressValue>();

foreach (var jobj in jarray.Children<JObject>()){

foreach (JProperty prop in jobj.Properties()){

values.Add(new AddressValue() { Label = prop.Name, Value = prop.Value.ToString() });

}

}

return values.ToArray();

}

class AddressValue{

public string Label { get; set; }

public string Value { get; set; }

}

但我有一个例外:

Exception thrown: 'Newtonsoft.Json.JsonSerializationException' in Newtonsoft.Json.DLL

Additional information: Unexpected token when deserializing object: StartObject. Path 'value[0]'.

编辑:我也试图将其保存到字典:

 [JsonProperty(PropertyName = "value")]

public Dictionary<string, string> Value{get; set;}

但我还有一个例外:

$exception  {"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON object (e.g. {\"name\":\"value\"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.\r\nPath 'param.value'."}

我做错了什么?谢谢您的回答。

回答:

您似乎想要Dictionary<string,

string>在JSON中将a表示为对象数组,其中每个嵌套对象都有一个来自字典的键和值。您可以使用以下转换器进行操作:

public class DictionaryToDictionaryListConverter<TKey, TValue> : JsonConverter 

{

class DictionaryDTO : Dictionary<TKey, TValue>

{

public DictionaryDTO(KeyValuePair<TKey, TValue> pair) : base(1) { Add(pair.Key, pair.Value); }

}

public override bool CanConvert(Type objectType)

{

return typeof(IDictionary<TKey, TValue>).IsAssignableFrom(objectType) && objectType != typeof(DictionaryDTO);

}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)

{

if (reader.TokenType == JsonToken.Null)

return null;

var token = JToken.Load(reader);

var dict = (IDictionary<TKey, TValue>)(existingValue as IDictionary<TKey, TValue> ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator());

if (token.Type == JTokenType.Array)

{

foreach (var item in token)

using (var subReader = item.CreateReader())

serializer.Populate(subReader, dict);

}

else if (token.Type == JTokenType.Object)

{

using (var subReader = token.CreateReader())

serializer.Populate(subReader, dict);

}

return dict;

}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)

{

var dict = (IDictionary<TKey, TValue>)value;

// Prevent infinite recursion of converters by using DictionaryDTO

serializer.Serialize(writer, dict.Select(p => new DictionaryDTO(p)));

}

}

然后在容器类中使用它,如下所示:

public class RootObject

{

[JsonProperty("value")]

[JsonConverter(typeof(DictionaryToDictionaryListConverter<string, string>))]

public Dictionary<string, string> Value { get; set; }

}

请注意,如果键不是唯一的,转换器将在读取过程中引发异常。

对于AddressValue您可以使用下面的转换器:

public class AddressValueConverter : JsonConverter

{

public override bool CanConvert(Type objectType)

{

return objectType == typeof(AddressValue);

}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)

{

if (reader.TokenType == JsonToken.Null)

return null;

var addressValue = (existingValue as AddressValue ?? new AddressValue());

var token = JObject.Load(reader);

var property = token.Properties().SingleOrDefault();

if (property != null)

{

addressValue.Label = property.Name;

addressValue.Value = (string)property.Value;

}

return addressValue;

}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)

{

var addressValue = (AddressValue)value;

serializer.Serialize(writer, new Dictionary<string, string> { { addressValue.Label, addressValue.Value } });

}

}

然后按以下方式使用它:

[JsonConverter(typeof(AddressValueConverter))]

public class AddressValue

{

public string Label { get; set; }

public string Value { get; set; }

}

public class RootObject

{

[JsonProperty("value")]

public List<AddressValue> Value { get; set; }

}

演示在这里摆弄了这两种选择。

以上是 Newtonsoft JSON.NET解析为自定义键/值对对象的数组 的全部内容, 来源链接: utcz.com/qa/423313.html

回到顶部