无法反序列化我的json

这是我的class级

实际上需要转换为良好的json数据的初始数据。 这是最初的坏事

{ "channels": { "heart-rate": { "events": { "$type": "System.Collections.Generic.List`1[[Project.Model.Activity+Channel+Event, Project]], mscorlib", "$values": [{ "$type": "Project.Model.ChannelEvents.HeartRateChannelEvent, LTF.MyPlan.ActivityUtil", "beatsPerMinute": 40, "offset": 0 } ] } }, "location": { "events": { "$type": "System.Collections.Generic.List`1[[Project.Model.Activity+Channel+Event, Project]], mscorlib", "$values": [{ "$type": "Project.Model.ChannelEvents.LocationChannelEvent, Project", "latitude": 0.0, "longitude": 0.0, "offset": 0 } ] } } } } public class LocationChannelEvent : Activity.Channel.Event { public double Latitude { get; set; } public double Longitude { get; set; } public float? Distance { get; set; } public float? Altitude { get; set; } ///  /// Speed in m/s ///  public float? Speed { get; set; } 

这是我的json数据,我无法反序列化。 我一直收到默认值,即使我改变了

 { "location": { "events": { "$type": "System.Collections.Generic.List`1[[Project.Model.Activity+Channel+Event, Project]], mscorlib", "$values": [{ "$type": "Project.Model.ChannelEvents.LocationChannelEvent, Project", "latitude": 0.0, "longitude": 0.0, "offset": 0 ] } } } 

我的自定义转换器

 public class CompactListConverter : JsonConverter { public const string TypeKey = "type"; public const string StructureKey = "structure"; public const string ListKey = "list"; ///  /// Only convert lists of non-enumerable class types. ///  ///  ///  public override bool CanConvert(Type objectType) { var objectTypeInfo = objectType.GetTypeInfo(); if (objectTypeInfo.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(List)) { var itemTypeInfo = objectTypeInfo.GenericTypeArguments.Single().GetTypeInfo(); if (itemTypeInfo.IsClass && !typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(itemTypeInfo)) { return true; } } return false; } ///  /// Generates a wrapper object containing type, structure, and the condensed list. ///  ///  ///  ///  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var list = (IList)value; if (list.Count > 0) { var array = new JArray(); var wrapper = GetWrapper(list, serializer); foreach (var item in list) { var obj = JObject.FromObject(item, serializer); var itemValues = new JArray(); foreach (var prop in obj.Properties()) { itemValues.Add(prop.Value); } array.Add(itemValues); } wrapper.Add(ListKey, array); wrapper.WriteTo(writer); } else { new JObject().WriteTo(writer); } } private JObject GetWrapper(IList list, JsonSerializer serializer) { var wrapper = new JObject {{TypeKey, list[0].GetType().AssemblyQualifiedName}}; var keys = new JArray(); var first = JObject.FromObject(list[0], serializer); foreach (var prop in first.Properties()) { keys.Add(new JValue(prop.Name)); } wrapper.Add(StructureKey, keys); return wrapper; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var wrapper = JObject.Load(reader); var itemType = Type.GetType(wrapper.GetValue(TypeKey).ToObject()); var array = wrapper.GetValue(ListKey) as JArray; var list = existingValue as IList ?? (IList) Activator.CreateInstance(typeof (List).MakeGenericType(new[] {itemType})); if (array != null && array.Count > 0) { var keys = wrapper.GetValue(StructureKey) as JArray ?? new JArray(); foreach (var itemValues in array.Children()) { var item = new JObject(); for (var i = 0; i < keys.Count; i++) { item.Add(new JProperty(keys[i].ToString(), itemValues[i])); } list.Add(item.ToObject(itemType, serializer)); } } return list; } } public class ChannelCompactingConverter : CompactListConverter { public override bool CanConvert(Type objectType) { return base.CanConvert(objectType) && typeof(IList).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo()); } } 

只要使用自定义JsonConverer就可以使用json.net以显示的格式反序列化和重新序列化List 。 这是必需的,因为默认情况下,对象集合是从JSON数组序列化的,但是在JSON中,对象集合以单个对象的稍微紧凑的forms被序列化,其中对象属性名称被序列化在称为"structure"的字符串数组中只有一次,并且对象本身表示为值数组的数组,内部数组与结构数组1-1对应。

因此,如果您创建以下转换器:

 public class StructuredListConverter : JsonConverter { const string typeName = "type"; const string structureName = "structure"; const string listName = "list"; public override bool CanConvert(Type objectType) { if (!typeof(ICollection).IsAssignableFrom(objectType)) return false; // This converter is only implemented for read/write collections. So no arrays. if (objectType.IsArray) return false; return true; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) return null; var collection = existingValue as ICollection ?? (ICollection) serializer.ContractResolver.ResolveContract(objectType).DefaultCreator(); var root = JObject.Load(reader); var structure = root[structureName] == null ? null : root[structureName].ToObject(); if (structure == null) throw new JsonSerializationException("structure not found."); var listToken = root[listName]; if (listToken == null || listToken.Type == JTokenType.Null) return collection; var list = listToken as JArray; if (list == null) throw new JsonSerializationException("list was not an array."); if (list == null || list.Count == 0) return collection; foreach (var item in list) { if (item == null || item.Type == JTokenType.Null) collection.Add(default(T)); else if (item.Type != JTokenType.Array) throw new JsonSerializationException(string.Format("Item was not an array: {0}", item)); else collection.Add(new JObject(item.Zip(structure, (i, n) => new JProperty(n, i))).ToObject()); } return collection; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var contract = serializer.ContractResolver.ResolveContract(typeof(T)) as JsonObjectContract; if (contract == null) throw new JsonSerializationException(string.Format("Type {0} is not mapped to a JSON object.", typeof(T))); var collection = (ICollection)value; writer.WriteStartObject(); // Write item type writer.WritePropertyName(typeName); serializer.Serialize(writer, typeof(T)); // Write structure (property names) var structure = contract.Properties.Where(p => p.Readable && !p.Ignored).Select(p => p.PropertyName).ToList(); writer.WritePropertyName(structureName); serializer.Serialize(writer, structure); // Write array of array of values var query = collection .Select(i => i == null ? null : contract.Properties.Where(p => p.Readable && !p.Ignored).Select(p => p.ValueProvider.GetValue(i))); writer.WritePropertyName(listName); serializer.Serialize(writer, query); writer.WriteEndObject(); } } 

并按如下方式定义数据模型:

 public class LocationChannelEvent : Activity.Channel.Event { public double Latitude { get; set; } public double Longitude { get; set; } public float? Distance { get; set; } public float? Altitude { get; set; } ///  /// Speed in m/s ///  public float? Speed { get; set; } } public class Location { [JsonConverter(typeof(StructuredListConverter))] public List events { get; set; } } public class RootObject { public Location location { get; set; } } 

您将能够反序列化并重新序列化显示的JSON。

原型小提琴 。

好吧,据我熟悉json这两件事,类和json是两个完全不同的东西! 所以很明显它不能像那样序列化。

在这种情况下我做的是将json反序列化为dynamic对象,然后查看C#创建的对象并将其与我的类进行比较。 你可以这样做:

 dynamic res = JsonConvert.Deserialize(json); 

然后,您可以在此处放置断点,查看解串器为您提供的内容。