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

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

问题描述

我正在尝试获取传入的 JSON 项并将它们绑定到列表框项,但 Visual Studio 告诉我我需要执行数组而不是对象?我从来没有这样做过……有人知道怎么做吗?

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?

我的根对象:

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

注意:Genetics、Price、BrandMaker 实际上不返回任何值,只返回一个值,如下所示:

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

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

JSON 文件/请求基本结果:

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

]

我的原始代码:

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

推荐答案

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

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.

因为您没有发布原始 JSON 示例.让我展示一个精简版,以保持简单和简短.

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

现在我们可以缩减 RootObject 类类型.我为我的属性使用了 Pascal 大小写,并使用 JSON.NET 属性将它们归因于帮助反序列化/序列化.

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

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

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

只需将这部分替换为您的 WebClient 调用即可获取您的 JSON 数据.

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

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

Now we can deserialize the JSON into a RootObject instance.

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

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

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;

这行不通.您不能将 RootObject 实例转换为 System.Collections.IEnumerable.这正是 ItemsSource 所期望的.

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

这是假设您的 JSON 数据仅返回一个 rootObject.您的列表框中只会显示一项.

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

现在让我们假设您的 JSON 数据返回一个 RootObjects 数组.例如称为items"的数组.其中包含一组 RootItems.

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": "https://github.com/geersch",
    "display": "This is another test",
    "genetics": [ "typeophere" ],
    "price": [ "$2000" ],
    "form": "another form"
    }]
}

反序列化同样容易.使用 JSON.NET 获取 RootObjects 的集合.

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

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

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

Now deserialize into a collection (IEnumerable).

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

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

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;

您收到的 JSON 数据似乎无效.在解析它之前,请确保对其进行修改,以便拥有有效的 JSON 对象.

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.

例如:

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

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

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