JSON无法反序列化到对象,需要阵列? [英] JSON Can't be Deserialized to Object, Needs Array?

查看:458
本文介绍了JSON无法反序列化到对象,需要阵列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图把传入的JSON项目并将其绑定到列表框中的项目,但我由Visual Studio,我需要做一个数组和对象不告诉?我从来没有做到这一点...任何人都知道如何



我RootObject:

 公共类RootObject 
{
公共字符串URL {搞定;组; }
公共字符串显示{搞定;组; }
公开名单<串GT;遗传学{搞定;组; }
公开名单<串GT;价格{搞定;组; }
公开名单<串GT; brandMaker {搞定;组; }
公共字符串形式{搞定;组; }
公共字符串dosornos {搞定;组; }
公共字符串数量{搞定;组; }
公共字符串制造{搞定;组; }
公共字符串mobURI {搞定;组; }
}

请注意:遗传学,价钱,BrandMaker实际上并不返回任何东西,但值,如下图所示:

 遗传学:
typeophere
],
价格:
$ 1400
],

JSON文件/请求基本结果:

  [
{
URL:N / A,
显示:,
遗传学:[
microogiz
],
价格:
96.016
],
brandMaker:[
Oshi琨缇Multikashi,大阪,JP
],
形式:切线,
dosornos :N / A,
数量:88G,
制造:。自制工业美国DIST,
mobURI:N / A
}

]



我原来的代码:

  //获取JSON通过网络
串ProviderURI = goURI;
Web客户端Web客户端=新的WebClient();
webClient.DownloadStringCompleted + =新的
DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(新的URI(ProviderURI));

无效webClient_DownloadStringCompleted(对象发件人,DownloadStringCompletedEventArgs E)
{
如果(e.Error!= NULL)
{
的回报;
}

VAR deserializedJSON = JsonConvert.DeserializeObject< RootObject>(e.Result);
lstBoxResults.ItemsSource = deserializedJSON; //或deserializedJSON.url.ToString();
}


解决方案

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



既然你没有张贴原始JSON的例子。让我提出一个下调的版本,让事情变得简单和短

  {
URL:HTTP ://www.stackoverflow.com,
显示:这是一个测试,
遗传学:[
typeophere
],
价格:
$ 1400
],
形式:一表
}

现在,我们可以修剪下来RootObject类类型。我用Pascal大小写为我的属性和归属他们JSON.NET属性,以协助deserialing /串行化。

  [的JSONObject( MemberSerialization = MemberSerialization.OptIn)] 
公共类RootObject
{
[JsonProperty(属性名=URL)]
公共字符串URL {搞定;组; }

[JsonProperty(属性名=显示)]
公共字符串显示{搞定;组; }

[JsonProperty(属性名=遗传学)]
公开名单<串GT;遗传学{搞定;组; }

[JsonProperty(属性名=价格)
公开名单<串GT;价格{搞定;组; }

[JsonProperty(属性名=表)
公共字符串表格{搞定;组; }
}



由于我不知道你在呼唤我只是存储在Web服务此JSON在文本文件中。 。将其标记为嵌入的资源,并从那里读

  JSON字符串; 
VAR资源= Application.GetResourceStream(新的URI(json.txt,UriKind.Relative));使用
(VAR读者=新的StreamReader(resource.Stream))
{
JSON = reader.ReadToEnd();
}



只需更换这部分与你的Web客户端调用来获取您的JSON数据。



现在,我们可以反序列化JSON成RootObject实例。

  VAR rootObject = JsonConvert.DeserializeObject< RootObject>(JSON); 



像宣传的那样。现在,您需要将其绑定到一个ListBox控件。如果你将鼠标悬停在你的列表框实例的属性的ItemSource你会看到工具提示中提到,您可以将其绑定到一个集合。好一个rootObject不是一个集合。你无法直接将它

  lstBoxResults.ItemsSource = rootObject; 

这是行不通的。你可以不RootObject实例转换为System.Collections.IEnumerable。这是什么的ItemsSource期待。



易于修复。让我们创建一个集合

  lstBoxResults.ItemsSource =新的List< RootObject> {} rootObject; 

这是假设你的JSON数据只返回rootObject。只有一个项目将出现在你的列表框。



现在让我们假设你的JSON数据返回RootObjects的数组。例如数组被称为包含RootItems集项目

  {
项目:[
{
URL:http://www.stackoverflow.com,
显示:这是一个测试,
遗传学:typeophere ],
价格:$ 1400],
形式:一表
},
{
URL:HTTP ://cgeers.com,
显示:这是另一个测试,
遗传学:[typeophere],
价格:$ 2000] ,
形式:另一种形式的
}]
}

Deserialing这同样容易。 。使用JSON.NET获得RootObjects集合

  VAR数据= JObject.Parse(JSON)[项目]; 

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

  VAR rootObjects = JsonConvert.DeserializeObject<&IEnumerable的LT; RootObject>>(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< RootObject>(JSON);


I am trying to take the incoming JSON items and bind them to listbox items but I am told by visual studio that I need to do an Array and not Object? I've never had to do this... Anyone know how?

My RootObject:

public class RootObject
{
    public string url { get; set; }
    public string display { get; set; }
    public List<string> genetics { get; set; }
    public List<string> price { get; set; }
    public List<string> 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; }
}

Note: Genetics, Price, BrandMaker don't actually return anything but a value, like below:

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

JSON FILE/REQUEST BASIC RESULT:

  [
{
    "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"
}

]

My original code:

// 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<RootObject>(e.Result);
    lstBoxResults.ItemsSource = deserializedJSON; // or deserializedJSON.url.ToString();
}

解决方案

Ok, you mention that genetics and price are arrays, but the returned JSON only contains one item. The rest of your RootObject are simple string properties.

Since you did not post a raw JSON example. Let me present a trimmed down version, to keep things simple and short.

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

Now we can trim down the RootObject class type. I used Pascal casing for my properties and attributed them with JSON.NET attributes to assist with the 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<string> Genetics { get; set; }

    [JsonProperty(PropertyName = "price")]
    public List<string> Price { get; set; }

    [JsonProperty(PropertyName = "form")]
    public string Form { get; set; }
}

Since I don't know the web service you are calling I just stored this JSON in a text file. Marked it as an embedded resource and read it from there.

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

Just replace this part with your WebClient call to obtain your JSON data.

Now we can deserialize the JSON into a RootObject instance.

var rootObject = JsonConvert.DeserializeObject<RootObject>(json);

Works as advertised. Now you need to bind it to a ListBox control. If you hover over the ItemSource property of your ListBox instance you'll see that the tooltip mentions that you can bind it to a collection. Well a single rootObject isn't a collection. You can't bind it directly.

lstBoxResults.ItemsSource = rootObject;

This will NOT work. You cannot convert a RootObject instance to a System.Collections.IEnumerable. Which is what ItemsSource is expecting.

Easy fix. Let's create a collection.

lstBoxResults.ItemsSource = new List<RootObject> { rootObject };

This is assuming that your JSON data only returns one rootObject. Only one item will appear in your ListBox.

Now let's suppose your JSON data returns an array of RootObjects. For example an array called "items" which contains a collection of 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"
    }]
}

Deserialing this is equally easy. Using JSON.NET obtain the collection of RootObjects.

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

Now deserialize into a collection (IEnumerable).

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

Since you now already have a collection of RootObject there is no need to create one yourself. You can directly bind it to the ListBox.

lstBoxResults.ItemsSource = rootObjects;

Seems like the JSON data you receive is invalid. Just before parsing it make sure you modify it so that you have a valid JSON object.

For example:

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

这篇关于JSON无法反序列化到对象,需要阵列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆