JSON.net – 字段是字符串或List

我有一种情况,从REST服务返回的JSON返回一个Movie-objects列表,所有这些都是通过大量信息进行的。 REST -service结果中的几个字段根据可用信息而变化。

一个例子:电影总是有一些屏幕截图(图像),演员和导演。 根据所讨论的电影,可能有一个或多个图像,一个或多个演员以及一个或多个导演。 几个案例的示例JSON:

 { "title": "Movie title", "images": [ "http://sofzh.miximages.com/c%23/img_0.jpg", "http://sofzh.miximages.com/c%23/img_1.jpg", "http://sofzh.miximages.com/c%23/img_2.jpg", "http://sofzh.miximages.com/c%23/img_3.jpg", "http://sofzh.miximages.com/c%23/img_4.jpg" ], "actors": [ "Steven Berkoff", "Nikolaj Coster-Waldau", "Julie Cox" ], "directors": "Simon Aeby" }, { "title": "Another movie", "images": "http://sofzh.miximages.com/c%23/img_1.jpg", "actors": "actor 1" "directors": [ "Justin Bieber", "Justin Timberlake" ] } 

问题是,使用JSON.net,我如何创建一个处理这个问题的转换器? 我一直在搜索互联网,但仍然没有找到解决方案。

关于同一个问题的另一个问题:如果字段是字符串列表或简单字符串,如何使JSON.NET以任何方式创建List(如果只是一个简单的字符串,则创建一个包含一个成员的列表)

编辑:这个REST服务不受我的控制

好吧,我这样做是为了好玩,但不要认为是有用的或最好的方式,无论如何……

将“动态”属性声明为对象,然后创建方法以获取像ImagesAsList或ImagesAsString之类的属性。 我用扩展方法做到了…..

 var movies = JsonConvert.DeserializeObject>(str); 

 class Movie { [JsonProperty("title")] public string Title { get; set; } [JsonProperty("images")] public object Images { get; set; } [JsonProperty("actors")] public object Actor { get; set; } [JsonProperty("directors")] public object Directors { get; set; } } 

扩展方法

 static class MovieExtension { public static List ImagesAsList(this Movie m) { var jArray = (m.Images as JArray); if (jArray == null) return null; return jArray.Select(x => x.ToString()).ToList(); } public static string ImagesAsString(this Movie m) { return m.Images as string; } } 

编辑

在阅读@yamen评论后,我做了一些改动,如:

 var settings = new JsonSerializerSettings(); settings.Converters.Add(new MoviesConverter()); var movies = JsonConvert.DeserializeObject>(str, settings); 

 class Movie { [JsonProperty("title")] public List Title { get; set; } [JsonProperty("images")] public List Images { get; set; } [JsonProperty("actors")] public List Actor { get; set; } [JsonProperty("directors")] public List Directors { get; set; } } 

变流器

 class MoviesConverter : JsonConverter { public override bool CanConvert(Type objectType) { return (objectType == typeof(string)) || (objectType == typeof(List)) ; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.StartArray) { var l = new List(); reader.Read(); while (reader.TokenType != JsonToken.EndArray) { l.Add(reader.Value as string); reader.Read(); } return l; } else { return new List { reader.Value as string }; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { //ToDo here we can decide to write the json as //if only has one attribute output as string if it has more output as list } } 

您将无法直接序列化到对象,但您可以手动执行此操作而无需太多精力。 JSON.Net包含LINQ to JSON。 首先定义一个方法,即使底层JSON不是数组,它也总是返回类型为T的列表:

 public List getSingleOrArray(JToken token) { if (token.HasValues) { return token.Select(m => m.ToObject()).ToList(); } else { return new List { token.ToObject() }; } } 

样品用法:

 JObject m1 = JObject.Parse(@"{ ""title"": ""Movie title"", ""images"": [ ""http://sofzh.miximages.com/c%23/img_0.jpg"", ""http://sofzh.miximages.com/c%23/img_1.jpg"" ], ""actors"": [ ""Steven Berkoff"", ""Julie Cox"" ], ""directors"": ""Simon Aeby"" }"); JObject m2 = JObject.Parse(@"{ ""title"": ""Another movie"", ""images"": ""http://sofzh.miximages.com/c%23/img_1.jpg"", ""actors"": ""actor 1"", ""directors"": [ ""Justin Bieber"", ""Justin Timberlake"" ] }"); IList m1_directors = getSingleOrArray(m1["directors"]); IList m2_directors = getSingleOrArray(m2["directors"]); 

m1_directory是一个包含单个元素的列表,m2_directors是一个包含两个元素的列表。