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); }