首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JSON不能反序列化为对象,需要数组吗?

JSON不能反序列化为对象,需要数组吗?
EN

Stack Overflow用户
提问于 2012-06-23 13:36:14
回答 2查看 15.1K关注 0票数 3

我正在尝试获取传入的JSON项,并将它们绑定到列表框项,但visual studio告诉我需要做一个数组而不是对象?我从来没做过这种事...有人知道怎么做吗?

我的RootObject:

代码语言:javascript
复制
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实际上只返回一个值,如下所示:

代码语言:javascript
复制
"genetics": [
    "typeophere"
],
"price": [
    "$1400"
],

JSON文件/请求基本结果:

代码语言:javascript
复制
  [
{
    "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"
}

]

我的原始代码:

代码语言:javascript
复制
// 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();
}
EN

回答 2

Stack Overflow用户

发布于 2012-06-23 14:25:49

好的,您提到了基因和价格是数组,但是返回的JSON只包含一项。RootObject的其余部分是简单的字符串属性。

因为您没有发布原始的JSON示例。让我介绍一个精简的版本,以保持简单和简短。

代码语言:javascript
复制
{
    "url": "http://www.stackoverflow.com",
    "display": "This is a test",
    "genetics": [
        "typeophere"
    ],
    "price": [
        "$1400"
    ],
    "form": "a form"
}

现在我们可以裁剪RootObject类类型了。我对我的属性使用了Pascal大小写,并用JSON.NET属性对它们进行了归属,以帮助进行反序列化/序列化。

代码语言:javascript
复制
[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存储在一个文本文件中。将其标记为嵌入式资源并从中读取。

代码语言:javascript
复制
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实例。

代码语言:javascript
复制
var rootObject = JsonConvert.DeserializeObject<RootObject>(json);

正如广告所说的那样。现在您需要将它绑定到一个ListBox控件。如果将鼠标悬停在ListBox实例的ItemSource属性上,您将看到工具提示提到可以将其绑定到集合。一个rootObject不是一个集合。不能直接绑定。

代码语言:javascript
复制
lstBoxResults.ItemsSource = rootObject;

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

很容易解决。让我们创建一个集合。

代码语言:javascript
复制
lstBoxResults.ItemsSource = new List<RootObject> { rootObject };

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

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

代码语言:javascript
复制
{
    "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的集合。

代码语言:javascript
复制
var data = JObject.Parse(json)["items"];

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

代码语言:javascript
复制
var rootObjects = JsonConvert.DeserializeObject<IEnumerable<RootObject>>(data.ToString());

因为您现在已经有了一个RootObject集合,所以不需要自己创建一个。您可以直接将其绑定到ListBox。

代码语言:javascript
复制
lstBoxResults.ItemsSource = rootObjects;

您收到的JSON数据似乎是无效的。就在解析它之前,请确保您修改了它,以便拥有一个有效的JSON对象。

例如:

代码语言:javascript
复制
json = json.Substring(json.IndexOf("[") + 1);
json = json.Substring(0, json.LastIndexOf("]"));
var rootObjects = JsonConvert.DeserializeObject<RootObject>(json);
票数 13
EN

Stack Overflow用户

发布于 2012-06-23 19:00:05

尝尝这个

代码语言:javascript
复制
RootObject rootObject;

if (json.startsWith("["))
{
  rootObject = JsonConvert.DeserializeObject<List<RootObject>>(json)[0];
}
else
{
  rootObject = JsonConvert.DeserializeObject<RootObject>(json);
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11167179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档