Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我如何使用JSON.Net解析它?_C#_Json - Fatal编程技术网

C# 我如何使用JSON.Net解析它?

C# 我如何使用JSON.Net解析它?,c#,json,C#,Json,我试图使用解析从第三方API返回的结果 如您所见,第一个块似乎是对后面的行块列的描述。我假设这不是标准做法,因为我在任何地方都找不到这种风格的参考。 由于它不是通常的名称:值对格式,我有点困惑 { cols: [{label: "name", type: 'string'}, {label: "caller_id_number", type: 'string'}, {label: "destination_number", type: 'string'}, {label:

我试图使用解析从第三方API返回的结果

如您所见,第一个块似乎是对后面的行块列的描述。我假设这不是标准做法,因为我在任何地方都找不到这种风格的参考。 由于它不是通常的名称:值对格式,我有点困惑

{ cols: [{label: "name", type: 'string'},
    {label: "caller_id_number", type: 'string'},
    {label: "destination_number", type: 'string'},
    {label: "call_start", type: 'datetime'},
    {label: "duration", type: 'number'},
    {label: "bill_seconds", type: 'number'},
    {label: "uuid", type: 'string'},
    {label: "call_bill_total", type: 'number'},
    {label: "recorded", type: 'boolean'}],
    rows: [
 {c:[{v: "mydomain.com"},
     {v: "1650"},
     {v: "01902321654"},
     {v: new Date(2011, 6, 19, 14, 12, 25)},
     {v: 3},
     {v: 0},
     {v: "07752f6c-b203-11e0-92e6-495a2db86d6d"},
     {v: 0},
     {v: true}]}
 ,{c:[{v: "mydomain.com"},{v: "1652"},{v: "034534514"},{v: new Date(2011, 6, 19, 14, 11, 34)},{v: 53},{v: 27},{v: "e8fe3a06-b202-11e0-92dd-495a2db86d6d"},{v: 0.05},{v: true}]},
 {c:[{v: "mydomain.com"},{v: "1650"},{v: "034534580"},{v: new Date(2011, 6, 19, 14, 11, 34)},{v: 11},{v: 9},{v: "e8dfb9dc-b202-11e0-92dc-495a2db86d6d"},{v: 0.02},{v: true}]},
 {c:[{v: "mydomain.com"},{v: "1650"},{v: "03453453600"},{v: new Date(2011, 6, 19, 14, 11, 11)},{v: 14},{v: 9},{v: "db7efd52-b202-11e0-92d6-495a2db86d6d"},{v: 0.02},{v: true}]},
 {c:[{v: "mydomain.com"},{v: "1650"},{v: "0345345947"},{v: new Date(2011, 6, 19, 14, 9, 41)},{v: 42},{v: 21},{v: "a59314bc-b202-11e0-92c7-495a2db86d6d"},{v: 0.04},{v: true}]},
 {c:[{v: "mydomain.com"},{v: "1653"},{v: "345345420"},{v: new Date(2011, 6, 19, 14, 9, 41)},{v: 28},{v: 0},{v: "a5a953f8-b202-11e0-92c8-495a2db86d6d"},{v: 0},{v: true}]},
 {c:[{v: "mydomain.com"},{v: "1650"},{v: "353453120"},{v: new Date(2011, 6, 19, 14, 8, 52)},{v: 28},{v: 5},{v: "885515bc-b202-11e0-92bd-495a2db86d6d"},{v: 0.02},{v: true}]},
 {c:[{v: "mydomain.com"},{v: "1653"},{v: "34534567"},{v: new Date(2011, 6, 19, 14, 8, 36)},{v: 10},{v: 3},{v: "7efc86d0-b202-11e0-92b8-495a2db86d6d"},{v: 0.02},{v: true}]},
 {c:[{v: "mydomain.com"},{v: "1650"},{v: "34534584"},{v: new Date(2011, 6, 19, 14, 7, 43)},{v: 34},{v: 13},{v: "5f1cfb60-b202-11e0-92b2-495a2db86d6d"},{v: 0.02},{v: true}]},
 {c:[{v: "mydomain.com"},{v: "1653"},{v: "34534534561"},{v: new Date(2011, 6, 19, 14, 6, 52)},{v: 52},{v: 0},{v: "411b3faa-b202-11e0-92ab-495a2db86d6d"},{v: 0},{v: true}]}]}
我只知道 var o=JObject.Parseresults; var records=o.SelectTokenrows.Selects=>s.ToList

理想情况下,我希望将记录拉回到类中,例如

public class CallDetailRecord
{
    public String Name { get; set; }
    public String CallerIdNumber { get; set; }
    public String DestinationNumber { get; set; }
    public DateTime CallStart { get; set; }
    public int Duration { get; set; }
    public String Uuid { get; set; }
    public Decimal CallBillTotal { get; set; }
    public bool Recorded { get; set; }
}

非常感谢您的帮助。

我不知道那是什么,但它不是JSON。它看起来像javascript,并且可能使用javascript引擎进行良好的解析

JSON规范:


验证器:

我不知道那是什么,但它不是JSON。它看起来像javascript,并且可能使用javascript引擎进行良好的解析

JSON规范:


验证程序:

虽然您的示例数据不是严格有效的JSON,但您解析它的尝试非常接近

您看到的布局有时会被一些人使用,他们认为可以通过别名字段名来改善结果集的大小。不幸的是,处理这个问题并不是那么简单,但是您可以将这些项目转回到对象中

在这些情况下,我更喜欢使用dynamic关键字和ExpandoObjects。如果愿意,您可以使用类,因为创建对象的大部分工作发生在下面的最终选择中,您可以重写它以将v元素集映射到类的字段中,而不是ExpandooObject。访问字段的语法是相同的,您可以从末尾将所有值写入控制台的代码段中看到这一点

注意,我已经编写了一个助手lambda来处理将Date映射到DateTime的情况。我只是指出这一点,因为您可能有更好的地方将此方法作为DateTime上的扩展方法;但复制并粘贴到代码的合适位置并没有什么害处

using System.Dynamic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

// ... other code removed

// You already have a means that loads your pseudo-json into results
// I used a file for the sake of this example
string results = File.ReadAllText(@"C:\temp\sample.json");

var o = JObject.Parse(results);
var headers = o.SelectToken("cols")
    .Select(x => { return new { label = x.SelectToken("label").Value<string>(), type = x.SelectToken("type").Value<string>()}; }).ToArray();
var rows = o.SelectToken("rows").Select(s => { return s.SelectToken("c");}).ToList();

Func<JConstructor, DateTime> MapAsDateTime = (s) =>
{
    // This is sloppy on my part, you should improve this as you like.
    List<int> v = new List<int>();
    foreach (JToken t in s)
    {
        v.Add(t.Value<int>());
    }
    return new DateTime(v[0], v[1], v[2], v[3], v[4], v[5]);
};

IEnumerable<dynamic> finalValues = rows.Select(s =>
    {
        var innerValues = s.ToList().Select(x => { return x.SelectToken("v"); }).ToArray();
        int i = 0;
        dynamic val = new ExpandoObject();
        IDictionary<string, object> valueMap = (IDictionary<string, object>)val;
        foreach (var innerValue in innerValues)
        {
            switch (headers[i].type)
            {
                case "string":
                    // NOTE: This can be improved, you could try to match and convert GUIDs with a regex or something else.
                    valueMap[headers[i].label] = innerValue.Value<string>();
                    break;
                case "datetime":
                    valueMap[headers[i].label] = MapAsDateTime((JConstructor)innerValue);
                    break;
                case "number":
                    // NOTE: This can be improved, your specific case needs decimal to handle things like 0.25, but many others could get by with just int
                    valueMap[headers[i].label] = innerValue.Value<decimal>();
                    break;
                case "boolean":
                    valueMap[headers[i].label] = innerValue.Value<bool>();
                    break;
                default:
                    // NOTE: You will need to add more cases if they 'define' more types.
                    throw new ArgumentException(string.Format("unhandled type \"{0}\" found in schema headers.", headers[i].type));
            }
            i++;
        }
        return val;
    });

foreach (dynamic d in finalValues)
{
    Console.WriteLine("name: {0}", d.name);
    Console.WriteLine("caller_id_number: {0}", d.caller_id_number);
    Console.WriteLine("destination_number: {0}", d.destination_number);
    Console.WriteLine("call_start: {0}", d.call_start);
    Console.WriteLine("duration: {0}", d.duration);
    Console.WriteLine("bill_seconds: {0}", d.bill_seconds);
    Console.WriteLine("uuid: {0}", d.uuid);
    Console.WriteLine("call_bill_total: {0}", d.call_bill_total);
    Console.WriteLine("recorded: {0}", d.recorded);
    Console.WriteLine("--");
}

虽然示例数据不是严格有效的JSON,但您解析它的尝试非常接近

您看到的布局有时会被一些人使用,他们认为可以通过别名字段名来改善结果集的大小。不幸的是,处理这个问题并不是那么简单,但是您可以将这些项目转回到对象中

在这些情况下,我更喜欢使用dynamic关键字和ExpandoObjects。如果愿意,您可以使用类,因为创建对象的大部分工作发生在下面的最终选择中,您可以重写它以将v元素集映射到类的字段中,而不是ExpandooObject。访问字段的语法是相同的,您可以从末尾将所有值写入控制台的代码段中看到这一点

注意,我已经编写了一个助手lambda来处理将Date映射到DateTime的情况。我只是指出这一点,因为您可能有更好的地方将此方法作为DateTime上的扩展方法;但复制并粘贴到代码的合适位置并没有什么害处

using System.Dynamic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

// ... other code removed

// You already have a means that loads your pseudo-json into results
// I used a file for the sake of this example
string results = File.ReadAllText(@"C:\temp\sample.json");

var o = JObject.Parse(results);
var headers = o.SelectToken("cols")
    .Select(x => { return new { label = x.SelectToken("label").Value<string>(), type = x.SelectToken("type").Value<string>()}; }).ToArray();
var rows = o.SelectToken("rows").Select(s => { return s.SelectToken("c");}).ToList();

Func<JConstructor, DateTime> MapAsDateTime = (s) =>
{
    // This is sloppy on my part, you should improve this as you like.
    List<int> v = new List<int>();
    foreach (JToken t in s)
    {
        v.Add(t.Value<int>());
    }
    return new DateTime(v[0], v[1], v[2], v[3], v[4], v[5]);
};

IEnumerable<dynamic> finalValues = rows.Select(s =>
    {
        var innerValues = s.ToList().Select(x => { return x.SelectToken("v"); }).ToArray();
        int i = 0;
        dynamic val = new ExpandoObject();
        IDictionary<string, object> valueMap = (IDictionary<string, object>)val;
        foreach (var innerValue in innerValues)
        {
            switch (headers[i].type)
            {
                case "string":
                    // NOTE: This can be improved, you could try to match and convert GUIDs with a regex or something else.
                    valueMap[headers[i].label] = innerValue.Value<string>();
                    break;
                case "datetime":
                    valueMap[headers[i].label] = MapAsDateTime((JConstructor)innerValue);
                    break;
                case "number":
                    // NOTE: This can be improved, your specific case needs decimal to handle things like 0.25, but many others could get by with just int
                    valueMap[headers[i].label] = innerValue.Value<decimal>();
                    break;
                case "boolean":
                    valueMap[headers[i].label] = innerValue.Value<bool>();
                    break;
                default:
                    // NOTE: You will need to add more cases if they 'define' more types.
                    throw new ArgumentException(string.Format("unhandled type \"{0}\" found in schema headers.", headers[i].type));
            }
            i++;
        }
        return val;
    });

foreach (dynamic d in finalValues)
{
    Console.WriteLine("name: {0}", d.name);
    Console.WriteLine("caller_id_number: {0}", d.caller_id_number);
    Console.WriteLine("destination_number: {0}", d.destination_number);
    Console.WriteLine("call_start: {0}", d.call_start);
    Console.WriteLine("duration: {0}", d.duration);
    Console.WriteLine("bill_seconds: {0}", d.bill_seconds);
    Console.WriteLine("uuid: {0}", d.uuid);
    Console.WriteLine("call_bill_total: {0}", d.call_bill_total);
    Console.WriteLine("recorded: {0}", d.recorded);
    Console.WriteLine("--");
}

我明白你的意思,我一定会看看这个,谢谢。我明白你的意思,我一定会看看这个,谢谢。很棒的东西,这让我摆脱了困境!正是字段名别名让我很头疼。非常感谢你花时间创作这部电影。这部电影太棒了,真让我摆脱了困境!正是字段名别名让我很头疼。非常感谢您花时间创建此文件。我今天发现,数据是使用生成的,突然变得更有意义。我今天发现,数据是使用生成的,突然变得更有意义。