【问题标题】:how to get data from json in c#?如何从 C# 中的 json 获取数据?
【发布时间】:2019-01-18 11:07:08
【问题描述】:

我从第三方获取 json 格式的 json 数据。 在某些情况下,我试图从“Id”中获取RollId,从“Data”中获取MType “数据”没有字段,有点空白。

当我们有“数据”时它就起作用了。在空白的情况下它不起作用。 对此有任何想法吗?有没有更好的方法来做到这一点?

这是 Json

      string json = @"{
  'root': {
    '_type': '_container',
    'Class': '.key.PModel',
    'Elements': {
      '_type': 'array<element>',
      '_data': [
        {
          '_type': 'element',
          'Class': '.key.PElement',
          'Id': {
            '_type': 'testId',
            'Class': '.key.PModel',
            'RollId': '.key.7157'
          },
          'Data': {
            '_type': 'p_model',
            'Class': '.key.Unsupported',
            'MType': '.TestMType',
            'Version': {
              '_type': 'test__version',
              'Class': '.key.TestVersion',

            }
          }
        },
        {
          '_type': 'element',
          'Class': '.key.PElement',
          'Id': {
            '_type': 'TestId',
            'Class': '.key.PModel',
            'RollId': '.key.11261'
          },
          'Data': '.ref.root.Elements.0.Data'
        },
        {
          '_type': 'element',
          'Class': '.key.PElement',
          'Id': {
            '_type': 'TestId',
            'Class': '.key.PModel',
            'RollId': '.key.7914'
          },
          'Data': '.ref.root.Elements.0.Data'
        }

      ]
    }
  }
}";

这是代码

public class Program
        {
            static void Main(string[] args)
            {
                //it provide json  
                var testCont = thirdpartyapi();
                var dataList = new List<TestResponse>();
                foreach (var testData in testCont.Elements())
                {
                    var data = new TestResponse();
                    data.col1 = Convert.ToInt32(testData.Id().RollId());
                    data.col2 = testData.Data().MType().ToString();
                    dataList.Add(data);
                }

            }


            public class TestResponse
            {
                public int col1 { get; set; }
                public string col2 { get; set; }


            }
        }

【问题讨论】:

  • 这个 JSON 无效。
  • @Adriani6 .. 抱歉,刚刚添加了 json 字符串。
  • @Harshit 您发布的代码未显示您尝试过的内容。 thirdpartyapiElements 是什么?您使用的是特定的反序列化器还是关于查询 JSON 数据的问题?

标签: c# json


【解决方案1】:

首先,尝试获取一个有效的格式良好的 json。你可以使用这个code beautify tool。然后您可以使用json2csharp 自动生成C# 类。最后,当您拥有 C# 类时,您可以应用 if 语句并检查属性是否为空。

生成的 C# 包装器:

public class Id
{
    public string _type { get; set; }
    public string Class { get; set; }
    public string RollId { get; set; }
}

public class Datum
{
    public string _type { get; set; }
    public string Class { get; set; }
    public Id Id { get; set; }
    public object Data { get; set; }
}

public class Elements
{
    public string _type { get; set; }
    public List<Datum> _data { get; set; }
}

public class Root
{
    public string _type { get; set; }
    public string Class { get; set; }
    public Elements Elements { get; set; }
}

public class RootObject
{
    public int encoding_version { get; set; }
    public Root root { get; set; }
}

【讨论】:

  • 谢谢!但我正在尝试从“数据”中获取“RollId”和“MType”,我们只能选择这两个字段吗?
  • 您实际上可以使用 Visual Studio 中内置的“Paste As Special”工具将 json 直接粘贴到类中。
【解决方案2】:

如果你只想从复杂的 JSON 中挑选几个字段,你可以考虑使用Cinchoo ETL - 一个开源库

下面的示例显示了如何从您的 json 中选择 RollIdMType

using (var r = new ChoJSONReader("## YOUR JSON FILE PATH ##")
    .WithJSONPath("$.._data")
    .WithField("RollId", jsonPath: "$..Id.RollId", fieldType: typeof(string))
    .WithField("MType", jsonPath: "$..Data.MType", fieldType: typeof(string))
    )

{
    foreach (var rec in r)
    {
        Console.WriteLine((string)rec.RollId);
        Console.WriteLine((string)rec.MType);
    }
}

希望对你有帮助。

【讨论】:

    【解决方案3】:

    最简单的方法是使用DataContractJsonSerializer

    Here你可以阅读更多关于它的信息。

    总而言之,您需要创建一个与您的 json 具有相同可能结果的模型。 然后你可以使用DataContractJsonSerializer 来创建你的模型对象,使用MemoryStream

    Here 你可以找到一个很好的工具来从 JSON 创建模型。 比如这个:

    public class Id
    {
        public string _type { get; set; }
        public string Class { get; set; }
        public string RollId { get; set; }
    }
    
    public class Datum
    {
        public string _type { get; set; }
        public string Class { get; set; }
        public Id Id { get; set; }
        public object Data { get; set; }
    }
    
    public class Elements
    {
        public string _type { get; set; }
        public List<Datum> _data { get; set; }
    }
    
    public class Root
    {
        public string _type { get; set; }
        public string Class { get; set; }
        public Elements Elements { get; set; }
    }
    
    public class RootObject
    {
        public int encoding_version { get; set; }
        public Root root { get; set; }
    }
    

    然后使用MemoryStreamDataContractJsonSerializer 从该JSON 创建RootObject 的对象。

    MemoryStream stream1 = new MemoryStream();  
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(RootObject));  
    
    stream1.Position = 0;  
    RootObject rootObject = (RootObject)ser.ReadObject(stream1);
    

    是的,正如 Adriani6 所提到的 - 你的 JSON 在这一点上是无效的:

    "Data": {
                "_type": "p_model",
                "Class": ".key.Unsupported",
                "MType": ".TestMType",
                "Version": {
                  "_type": "test__version",
                  "Class": ".key.TestVersion",
    
                }
    

    最后有一个,,这是不允许的。

    【讨论】:

    • 谢谢!但我正在尝试从“数据”中获取“RollId”和“MType”,我们可以只选择这两个字段吗?
    • DataContractSerializer 不是一个好的选择。这是一个旧的实现,只是作为一种权宜之计。他们处理日期的方式与事实上的标准 ISO8601 不兼容。最流行的反序列化器是 JSON.NET,它也用于 ASP.NET Web API 和 ASP.NET Core。
    • 啊好吧,不知道。我不太会使用 JSON,当我这样做时,我会使用 DataContractSerializer。但很高兴知道未来!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    相关资源
    最近更新 更多