7

我正在尝试使用 Json.NET 处理 JSON 结构并遇到了一些问题:

当 JSON 包含未命名的数组时,我的类不起作用。

json示例:

{
    "graph_property" : [{
            "name" : "calculation_method",
            "value" : "Arithmetic"
        }, {
            "name" : "graph_type",
            "value" : "TIME"
        }
    ],
    "measurement" : [{
            "id" : "9997666",
            "alias" : "Measurement (TxP)[IE]-Home Page - Total Time (seconds)",
            "bucket_data" : [{
                    "name" : "2013-MAR-18 12:00 AM",
                    "id" : 1,
                    "perf_data" : {
                        "value" : "2.244",
                        "unit" : "seconds"
                    },
                    "avail_data" : {
                        "value" : "99.67",
                        "unit" : "percent"
                    },
                    "data_count" : {
                        "value" : "299",
                        "unit" : "#"
                    }
                }
            ],
            "graph_option" : [{
                    "name" : "perfwarning",
                    "value" : "-",
                    "unit" : "seconds"
                }, {
                    "name" : "perfcritical",
                    "value" : "-",
                    "unit" : "seconds"
                }, {
                    "name" : "availwarning",
                    "value" : "-",
                    "unit" : "percent"
                }, {
                    "name" : "availcritical",
                    "value" : "-",
                    "unit" : "percent"
                }, {
                    "name" : "bucketsize",
                    "value" : "86400",
                    "unit" : "seconds"
                }, {
                    "name" : "rows",
                    "value" : "1",
                    "unit" : "#"
                }, {
                    "name" : "pagecomponent",
                    "value" : "Total Time",
                    "unit" : "seconds"
                }, {
                    "name" : "avg_perf",
                    "value" : "2.244",
                    "unit" : "seconds"
                }, {
                    "name" : "avg_avail",
                    "value" : "99.67",
                    "unit" : "percent"
                }, {
                    "name" : "total_datapoint_count",
                    "value" : "300",
                    "unit" : "#"
                }, {}

            ]
        }, {
            "id" : "9997666",
            "alias" : "Measurement (TxP)[IE]-Women - Total Time (seconds)",
            "bucket_data" : [{
                    "name" : "2013-MAR-18 12:00 AM",
                    "id" : 1,
                    "perf_data" : {
                        "value" : "0.979",
                        "unit" : "seconds"
                    },
                    "avail_data" : {
                        "value" : "100.00",
                        "unit" : "percent"
                    },
                    "data_count" : {
                        "value" : "299",
                        "unit" : "#"
                    }
                }
            ],
            "graph_option" : [{
                    "name" : "perfwarning",
                    "value" : "-",
                    "unit" : "seconds"
                }, {
                    "name" : "perfcritical",
                    "value" : "-",
                    "unit" : "seconds"
                }, {
                    "name" : "availwarning",
                    "value" : "-",
                    "unit" : "percent"
                }, {
                    "name" : "availcritical",
                    "value" : "-",
                    "unit" : "percent"
                }, {
                    "name" : "bucketsize",
                    "value" : "86400",
                    "unit" : "seconds"
                }, {
                    "name" : "rows",
                    "value" : "1",
                    "unit" : "#"
                }, {
                    "name" : "pagecomponent",
                    "value" : "Total Time",
                    "unit" : "seconds"
                }, {
                    "name" : "avg_perf",
                    "value" : "0.979",
                    "unit" : "seconds"
                }, {
                    "name" : "avg_avail",
                    "value" : "100.00",
                    "unit" : "percent"
                }, {
                    "name" : "total_datapoint_count",
                    "value" : "299",
                    "unit" : "#"
                }, {}

            ]
        }
    ],
    "link" : {
        "type" : "application/json",
        "href" : "http://api.website.tld?format=json",
        "rel" : "slotmetadata"
    }
}

Json.NET 类:

using System;
using System.Collections.Generic;

namespace CAKR.Graph
{
    /// <summary>
    /// Description of KN_Graph.
    /// </summary>
    public class GraphProperty
    {
        public string name { get; set; }
        public string value { get; set; }
    }

    public class PerfData
    {
        public string value { get; set; }
        public string unit { get; set; }
    }

    public class AvailData
    {
        public string value { get; set; }
        public string unit { get; set; }
    }

    public class DataCount
    {
        public string value { get; set; }
        public string unit { get; set; }
    }

    public class BucketData
    {
        public string name { get; set; }
        public int id { get; set; }
        public PerfData perf_data { get; set; }
        public AvailData avail_data { get; set; }
        public DataCount data_count { get; set; }
    }

    public class GraphOption
    {
        public string name { get; set; }
        public string value { get; set; }
        public string unit { get; set; }
    }

    public class Measurement
    {
        public string id { get; set; }
        public string alias { get; set; }
        public List<BucketData> bucket_data { get; set; }
        public List<GraphOption> graph_option { get; set; }
    }

    public class Link
    {
        public string type { get; set; }
        public string href { get; set; }
        public string rel { get; set; }
    }

    public class RootObject
    {
        public List<GraphProperty> graph_property { get; set; }
        public List<Measurement> measurement { get; set; }
        public Link link { get; set; }
    }
}

我的代码:

var myObject = JsonConvert.DeserializeObject<CAKR.Graph.Measurement>(MyJsonString);

我不确定为什么我没有得到一个包含“测量”子数组数据的对象。如果我插入命名值,它可以工作......

4

4 回答 4

9

所以我努力了很长一段时间才能让它发挥作用。然而最终解决方案并没有那么困难。希望我的回答能帮助一些人。

我的解决方案是

  1. 使用 nu.get 将 JSON.net 安装到您的项目中
  2. 使您的 JSON 对象包括数组中的数组等。确保对象的格式正确!例子...

{“产品明细”:[

  {
      "ProjectImg"    : "http://placehold.it/400x300",
      "Category"      : "Cars",
      "ProjectTitle"  : "Cars of the future",
      "ProjectDesc"   : "Test project",
      "GenSpecList"   : ["Specs1", "Specs2", "Specs3", "Specs4"],
      "OptionList"    : [{    "OptionNr"  : "1",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          },
                          {   "OptionNr"  : "2",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          },
                          {   "OptionNr"  : "3",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          },
                          {   "OptionNr"  : "4",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          },
                          {   "OptionNr"  : "5",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          },
                          {   "OptionNr"  : "6",
                              "Options"   : ["Opt1", "Opt2", "Opt3"]
                          }
                        ],
      "Articles"      : [{    "tileImg" : "'Images/Project/1.jpg'",
                              "tileTit" : "Title1",
                              "tileArt" : "Article text here..."
                          },
                          {
                              "tileImg" : "'Images/Project/2.jpg'",
                              "tileTit" : "Title2",
                              "tileArt" : "Article text here..."
                          },
                          {
                              "tileImg" : "'Images/Project/3.jpg'",
                              "tileTit" : "Title3",
                              "tileArt" : "Article text here..."
                          },
                          {
                              "tileImg" : "'Images/Project/4.jpg'",
                              "tileTit"   : "Title4",
                              "tileArt"   : "Article text here..."
                          }
                         ]
  }
]
}
  1. 转到 json2csharp.com 并将您的 JSON 对象复制到输入框中,然后单击生成按钮。将生成的 csharp 模型(这实际上是解决我的难题的关键!)复制到您的 ViewModel 中。
  2. 就我而言,json2csharp.com 生成的所有类的主要类是 RootObject,如下所示

    public class Article
    {
        public string tileImg { get; set; }
        public string tileTit { get; set; }
        public string tileArt { get; set; }
    }
    
    public class OptionList
    {
        public string OptionNr { get; set; }
        public List<string> Options { get; set; }
    }
    
    public class ProductDetail
    {
        public string ProjectImg { get; set; }
        public string Category { get; set; }
        public string ProjectTitle { get; set; }
        public string ProjectDesc { get; set; }
        public List<string> GenSpecList { get; set; }
        public List<OptionList> OptionList { get; set; }
        public List<Article> Articles { get; set; }
    }
    
    public class RootObject
    {
        public List<ProductDetail> ProductDetail { get; set; }
    }
    
  3. 然后在控制器中使用以下代码(这里只是复制了完整的文件)

    using Project.Details; //<-- this is my ViewModel namespace name
    using Newtonsoft.Json;
    using System.IO;
    using System.Threading.Tasks;
    
    namespace WebApplication.Controllers
    {
        public class JSONController : Controller
        {
            //
            // GET: /JSON/
            public async Task<ActionResult> Index()
            {
                StreamReader file = new StreamReader("C:\\Users\\YourName\\etc\\File.json");
                String json = await file.ReadToEndAsync();
    
                var Project = JsonConvert.DeserializeObject<RootObject>(json);
    
                return View();
            }
        }
    }
    

现在一切正常,数组中的数组等。希望您发现我的解决方案有帮助,请注意我不是一个顽固的程序员,所以如果我错过了效率方面的事情,我希望从您那里得到一些改进此代码的提示...

最好的问候,雷蒙德

于 2014-02-01T13:05:11.650 回答
4

You are almost there. Just use

var myObject = JsonConvert.DeserializeObject<CAKR.Graph.RootObject>(MyJsonString);

instead of

var myObject = JsonConvert.DeserializeObject<CAKR.Graph.Measurement>(MyJsonString);
于 2013-03-19T18:22:42.853 回答
2

首先,您并不需要Measurement完全按照MyJsonString. 您可以使用JsonProperty属性并装饰您的类属性。

另一件事是,如果您想反序列化您的部分MyJsonString并仅提取数组Measurement,您应该为方法提供正确的 T 类型Deserialize(在您的情况下是IEnumerable<Measurement>.

以下代码应该会有所帮助:

    dynamic context = JObject.Parse(MyJsonString);
    var myObject = JsonConvert.DeserializeObject<IEnumerable<Measurement>>(context.measurement.ToString());
于 2013-03-19T18:30:01.530 回答
0

我使用一种非常简单的方法来反序列化 Json 数组。而不是使用具有大量公共变量的大量公共类。我只是使用一个动态对象并将 json 作为对象传递给 JSONConvert.DeserializeObject。

这就是它的工作方式。假设我有以下 JSON:

string json = { 'Name': 'John Doe', 
  'Address': { 'City': 'Atlanta', 'State': 'GA' }, 
  'Age': 30}

我可以将字符串 json 传递给 JSONConvert.DeserializeObject。

dynamic outputArray = JsonConvert.DeserializeObject(json);

然后使用刚刚创建的动态项目,我可以像这样收集 Json 数据。

string getName = outputArray.Name //This will return "John Doe"

如果您的 Json 中有一个数组,您可以使用

string getCity = outputArray.Address.City; //This will return "Atlanta".

在没有公共变量集群的情况下,很容易更改从哪里提取数据……如果需要,您仍然可以将值保存到公共变量中。

以下是我如何使用完整方法:

using (var client = new WebClient())
        {
            string json = client.DownloadString(url);
            string output = json.ToString();

            dynamic outputArray = JsonConvert.DeserializeObject(output);

            string _age = outputArray.age;
            string appID = outputArray.data.app_id;

            Debug.Write(outputArray.Something); //Just match value of json        
        }
于 2015-04-02T16:38:48.327 回答