使用带有动态数据的 JSon.NET 反序列化 JSON

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8738031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 18:08:00  来源:igfitidea点击:

Deserializing JSON using JSon.NET with dynamic data

jsonwindows-phone-7json.netdeserialization

提问by Bil Simser

I'm trying to deserialize some JSON data into objects for an application. Up until now it's been fine because the properties on the JSON data was static (key with a value). Now I've got a result where the key is a dynamic piece of data.

我正在尝试将一些 JSON 数据反序列化为应用程序的对象。到目前为止,它一直很好,因为 JSON 数据上的属性是静态的(带有值的键)。现在我得到了一个结果,其中关键是一段动态数据。

Here's an example JSON url:

这是一个示例 JSON 网址:

http://en.wikipedia.org/w/api.php?action=query&format=json&pageids=6695&prop=info

http://en.wikipedia.org/w/api.php?action=query&format=json&pageids=6695&prop=info

The resulting JSON for this is:

生成的 JSON 是:

{ "query" : { "pages" : { "6695" : { "counter" : "",
          "lastrevid" : 468683764,
          "length" : 8899,
          "ns" : 0,
          "pageid" : 6695,
          "title" : "Citadel",
          "touched" : "2012-01-03T19:16:16Z"
        } } } }

Okay, that's great except I can't deserialize the "pages" data into an object. If I were to define a class for the pages it would have to look like this:

好的,这很好,除了我无法将“页面”数据反序列化为对象。如果我要为页面定义一个类,它必须如下所示:

public class 6695
{
    public string counter { get; set; }
    public int lastrevid { get; set; }
    public int length { get; set; }
    public int ns { get; set; }
    public int pageid { get; set; }
    public string title { get; set; }
    public string touched { get; set; }
}

In order to deserialze the contents (using JsonConvert.Deserialize(jsondata)) and we all know we can't have a class called 6695. Not only that, the name of the class would have to be different (for example pageid=7145 would have to be the 7145 class).

为了反序列化内容(使用 JsonConvert.Deserialize(jsondata)),我们都知道我们不能有一个名为 6695 的类。不仅如此,类的名称必须不同(例如 pageid=7145 会必须是 7145 类)。

I can seem to pluck some values out if I use something like JObject.Parse(content) and then access items as JArrays but it's pretty ugly and I'm still stuck on trying to get out the data from the pages array.

如果我使用 JObject.Parse(content) 之类的东西,然后将项目作为 JArrays 访问,我似乎可以提取一些值,但它非常难看,而且我仍然试图从 pages 数组中获取数据。

Looking for someone to help with this. I don't think it's uncommon, it's just not JSON data I've come across before and not sure how to handle it.

想找人帮忙解决这个问题。我认为这并不罕见,这不是我以前遇到的 JSON 数据,但不确定如何处理它。

Thanks!

谢谢!

PS forgot to mention this is on Windows Phone 7 so "dynamic" isn't available!

PS忘了提到这是在Windows Phone 7上,所以“动态”不可用!

回答by Buildstarted

The simplest method. In this particular case would probably be to go dynamic.

最简单的方法。在这种特殊情况下可能会去dynamic

dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
var lastRevId = data.query.pages["6695"].lastrevid;

You can reference any element by it's []name so you can do something like data["query"]["pages"]["6695"]["lastrevid"]. This will get by all those little objects where the name isn't valid in c#.

您可以通过[]名称引用任何元素,这样您就可以执行类似data["query"]["pages"]["6695"]["lastrevid"]. 这将通过名称在 c# 中无效的所有小对象获得。

回答by prabir

Here is how you do using https://github.com/facebook-csharp-sdk/simple-json( https://nuget.org/packages/SimpleJson).

以下是如何使用https://github.com/facebook-csharp-sdk/simple-json( https://nuget.org/packages/SimpleJson)。

var text = "{\"query\":{\"pages\":{\"6695\":{\"pageid\":6695,\"ns\":0,\"title\":\"Citadel\",\"touched\":\"2012-01-03T19:16:16Z\",\"lastrevid\":468683764,\"counter\":\"\",\"length\":8899}}}}";

(Using dynamic)

(使用动态)

dynamic json = SimpleJson.DeserializeObject(text);
string title = json.query.pages["6695"].title;

foreach (KeyValuePair<string, dynamic> page in json.query.pages)
{
    var id = page.Key;
    var pageId = page.Value.pageid;
    var ns = page.Value.ns;
}

(Using strongly typed classes)

(使用强类型类)

class result
{
    public query query { get; set; }
}
class query
{
    public IDictionary<string, page> pages { get; set; }
}
class page
{
    public long pageid { get; set; }
    public string title { get; set; }
}

var result = SimpleJson.DeserializeObject<result>(text);

[Update]

[更新]

on windows phone where dynamic is not supported and you don't want to use strongly typed classes.

在不支持动态且您不想使用强类型类的 Windows 手机上。

var json = (IDictionary<string, object>)SimpleJson.DeserializeObject(text);
var query = (IDictionary<string, object>)json["query"];
var pages = (IDictionary<string, object>)query["pages"];
var pageKeys = pages.Keys;
var page = (IDictionary<string, object>)pages["6695"];
var title = (string)page["title"];

回答by Nour Lababidi

I hope the below example will help. I always design a model that match the json. It is much better to work with the object when it is your own model design.

我希望下面的例子会有所帮助。我总是设计一个与json匹配的模型。当对象是您自己的模型设计时,最好使用它。

It is very easy to generate the c# model from the json. I use this website to generate the model: http://json2csharp.com

从 json 生成 c# 模型非常容易。我使用这个网站来生成模型:http: //json2csharp.com

A complete example is:

一个完整的例子是:

C# Code:

C# 代码:

    var targetsObject = Newtonsoft.Json.JsonConvert.DeserializeObject<YourModel>(jsonString);

JSON:

JSON:

    {
      "investors": [
        {
          "name": "06",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": "6.0"
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "07",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": "7.0"
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "08",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": "7.0"
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "09",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "10",
          "programs": [
            {
              "name": "Conventional",
              "value": ""
            },
            {
              "name": "FHA - Standard",
              "value": ""
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": ""
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": "2.0"
            }
          ]
        },
        {
          "name": "11",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "6.0"
            },
            {
              "name": "VA IRRRL",
              "value": "6.0"
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "12",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": "6.0"
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "13",
          "programs": [
            {
              "name": "Conventional",
              "value": ""
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": ""
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": "2.0"
            }
          ]
        }
      ]
    }

Model:

模型:

    public class Program
    {
        public string name { get; set; }
        public string value { get; set; }
    }

    public class Investor
    {
        public string name { get; set; }
        public List<Program> programs { get; set; }
    }

    public class RootObject
    {
        public List<Investor> investors { get; set; }
    }

回答by N_A

Using Json.net you can just do:

使用 Json.net 你可以这样做:

Dictionary<string,object> result = JsonConvert.DeserializeObject<Dictionary<string,object>>(json);
foreach(var item in result)
    Console.WriteLine(item.Key + " " + item.Value);

回答by vitaly-t

Maybe you could just use one reserved attribute to contain the object type, and then use the base type as shown in this article: Dynamic types with JSON.NET

也许您可以只使用一个保留属性来包含对象类型,然后使用基本类型,如本文所示:Dynamic types with JSON.NET

回答by Tom

How about a simple search and replace in the JSON string ? While it might not be the most elegant solution, it would possibly be the most pragmatic one.

在 JSON 字符串中进行简单的搜索和替换怎么样?虽然它可能不是最优雅的解决方案,但它可能是最实用的解决方案。