JSON无法反序列化为对象,需要数组吗?

我试图获取传入的JSON项目并将它们绑定到列表框项目,但我被视觉工作室告知我需要做一个数组而不是对象? 我从来没有这样做过……任何人都知道怎么做?

我的RootObject:

public class RootObject { public string url { get; set; } public string display { get; set; } public List genetics { get; set; } public List price { get; set; } public List brandMaker { get; set; } public string form { get; set; } public string dosornos { get; set; } public string qty { get; set; } public string mfg { get; set; } public string mobURI { get; set; } } 

注意:Genetics,Price,BrandMaker实际上并没有返回任何值,如下所示:

 "genetics": [ "typeophere" ], "price": [ "$1400" ], 

JSON文件/请求基本结果:

  [ { "url": "N/A", "display": "", "genetics": [ "microogiz" ], "price": [ "96.016" ], "brandMaker": [ "Oshi Kunti Multikashi, Osaka, JP" ], "form": "tangent", "dosornos": "n/a", "qty": "88G", "mfg": "SelfMade Industries, USA Dist.", "mobURI": "n/a" } 

]

我原来的代码:

 // Get JSON via WEB string ProviderURI = goURI; webClient webClient = new WebClient(); webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted); webClient.DownloadStringAsync(new Uri(ProviderURI)); void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { if (e.Error != null) { return; } var deserializedJSON = JsonConvert.DeserializeObject(e.Result); lstBoxResults.ItemsSource = deserializedJSON; // or deserializedJSON.url.ToString(); } 

好的,你提到遗传和价格是数组,但返回的JSON只包含一个项目。 RootObject的其余部分是简单的字符串属性。

由于您没有发布原始JSON示例。 让我展示一个精简版本,以保持简单和简短。

 { "url": "http://www.stackoverflow.com", "display": "This is a test", "genetics": [ "typeophere" ], "price": [ "$1400" ], "form": "a form" } 

现在我们可以减少RootObject类的类型。 我使用Pascal大小写为我的属性,并将它们与JSON.NET属性相关联,以帮助进行deserialing / serializing。

 [JsonObject(MemberSerialization = MemberSerialization.OptIn)] public class RootObject { [JsonProperty(PropertyName = "url")] public string Url { get; set; } [JsonProperty(PropertyName = "display")] public string Display { get; set; } [JsonProperty(PropertyName = "genetics")] public List Genetics { get; set; } [JsonProperty(PropertyName = "price")] public List Price { get; set; } [JsonProperty(PropertyName = "form")] public string Form { get; set; } } 

由于我不知道您正在调用的Web服务,因此我将此JSON存储在文本文件中。 将其标记为嵌入式资源并从那里读取。

 string json; var resource = Application.GetResourceStream(new Uri("json.txt", UriKind.Relative)); using (var reader = new StreamReader(resource.Stream)) { json = reader.ReadToEnd(); } 

只需使用WebClient调用替换此部分即可获取JSON数据。

现在我们可以将JSON反序列化为RootObject实例。

 var rootObject = JsonConvert.DeserializeObject(json); 

像宣传的那样工作。 现在需要将它绑定到ListBox控件。 如果将鼠标hover在ListBox实例的ItemSource属性上,您将看到工具提示提到您可以将其绑定到集合。 好吧,单个rootObject不是集合。 你不能直接绑定它。

 lstBoxResults.ItemsSource = rootObject; 

这不起作用。 您无法将RootObject实例转换为System.Collections.IEnumerable。 这是ItemsSource的期望。

轻松修复。 我们来创建一个集合。

 lstBoxResults.ItemsSource = new List { rootObject }; 

这假设您的JSON数据仅返回一个rootObject。 ListBox中只会显示一个项目。

现在让我们假设您的JSON数据返回一个RootObject数组。 例如,一个名为“items”的数组,其中包含RootItems的集合。

 { "items": [ { "url": "http://www.stackoverflow.com", "display": "This is a test", "genetics": [ "typeophere" ], "price": [ "$1400" ], "form": "a form" }, { "url": "http://cgeers.com", "display": "This is another test", "genetics": [ "typeophere" ], "price": [ "$2000" ], "form": "another form" }] } 

去除这个同样容易。 使用JSON.NET获取RootObjects的集合。

 var data = JObject.Parse(json)["items"]; 

现在反序列化为一个集合(IEnumerable)。

 var rootObjects = JsonConvert.DeserializeObject>(data.ToString()); 

由于您现在已经拥有RootObject集合,因此无需自己创建。 您可以直接将其绑定到ListBox。

 lstBoxResults.ItemsSource = rootObjects; 

好像您收到的JSON数据无效。 在解析之前,请确保修改它以便拥有有效的JSON对象。

例如:

 json = json.Substring(json.IndexOf("[") + 1); json = json.Substring(0, json.LastIndexOf("]")); var rootObjects = JsonConvert.DeserializeObject(json); 

试试这个

 RootObject rootObject; if (json.startsWith("[")) { rootObject = JsonConvert.DeserializeObject>(json)[0]; } else { rootObject = JsonConvert.DeserializeObject(json); }