使用Newtonsoft.json映射到C#.net模型的JSON的另一种读取方法

时间:2018-08-04 10:09:20

标签: c# json json.net

没有为我的主题提供最佳/适当的标题的歉意,如果您的标题比我更好,将很高兴对其进行更新。

我当前的问题是我必须处理一个使用Newtonsoft.JSON的现有代码,该代码从.JSON文件(从第三方提供)中读取json。它也映射到现有的类。我不确定这是否是通过执行IF-ELSE来到达正确的json节点的正确方法,也许有人会拥有除我之外的其他选择/更好的方法。谢谢。

这不是确切的代码,但是我复制了与我的问题有关的代码。

PET.JSON文件:(JSON文件是由第三方提供的,结构/模式与下面的示例相同,并且由于其格式而已,因此不允许更改JSON格式)

{
  "Pet": {
    "Dog": {
      "cute": true,
      "feet": 4
    },
    "Bird": {
      "cute": false,
      "feet": 2
    }
  }
}  

宠物类和子类(这是第三方标准结构,我无权对其进行修改)

public class Pet
{
    public Dog dog { get; set; }
    public Bird bird { get; set; }

    public class Dog {
        public bool cute { get; set; }
        public int feet { get; set; }
    }

    public class Bird
    {
        public bool cute { get; set; }
        public int feet { get; set; }
    }
}  

宠物阅读器(我必须使用映射到上述模型的反序列化Json对象,还没有权限修改其实现“但”我必须自行管理如何使用ReadPetJSON的返回值())

public static Pet ReadPetJSON()
{
    string JSON_TEXT = File.ReadAllText("PET.JSON");
    Pet pet = Newtonsoft.Json.JsonConvert.DeserializeObject<Pet>(JSON_TEXT);
    return pet;
}  

更新: 我发现了有关使用Reflection的知识,并且可以传递变量名称来查找PropertyName。谢谢大家的帮助和投入,谢谢

http://mcgivery.com/c-reflection-get-property-value-of-nested-classes/

// Using Reflection
Pet pet = ReadPetJSON();

// Search Bird > feet using 'DOT' delimiter
string searchBy = "bird.feet"

foreach (String part in searchBy.Split('.'))
{
    if (pet == null) { return null; }

    Type type = pet.GetType();
    PropertyInfo info = type.GetProperty(part);
    if (info == null) { return null; }  // or make a catch for NullException

    pet = info.GetValue(pet, null);
}

var result = pet.ToString(); // Object result in string
Console.WriteLine("Bird-Feet: {0}", result);

输出:

Bird-Feet: 2

3 个答案:

答案 0 :(得分:2)

好吧,您可以改用这些类,然后在“宠物”列表上循环。

  public class JsonParsed
{
    public Dictionary<string, Attribute> Pet { get; set; } 
}

public class Attribute
{
    public bool cute { get; set; }
    public int feet { get; set; }
}

键包含宠物的名称,“属性”包含其他属性。

  var json = @"{'Pet': {'Dog': {'cute': true,'feet': 4},'Bird': {'cute': 
  false,'feet': 2}}}";
  var obj = JsonConvert.DeserializeObject<JsonParsed>(json);
 foreach (var element in obj.Pet)
 {
    Console.WriteLine(element.Key  + " has " + element.Value.feet);
 }

答案 1 :(得分:0)

  

我正在这样想,但是我知道这是不可能的。

是的,下面的代码可以实现。

您必须像Querying这样的json

string JSON_TEXT = File.ReadAllText("PET.JSON");

JObject jObject = JObject.Parse(JSON_TEXT);

//This is your search term
string search = "Dog";  //or "Bird", or "Lion", or "Tiger", or "Eagle" or anything that are present it your json

bool cute = (bool)jObject["Pet"][search]["cute"];
int feet = (int)jObject["Pet"][search]["feet"];

string temp = $"My {search} is cute = {cute} and feet = {feet} ";

//If you want it in your strongly type then
Dog dog = jObject["Pet"][search].ToObject<Dog>();
Bird bird = jObject["Pet"][search].ToObject<Bird>();

输出:

enter image description here

在上面的代码中

[“ Pet”] =>您的json的第0个位置级别节点。

[search] =>您的json的第一个位置级别节点。

[“ cute”]或[“ feet”] => json的第二个位置级别节点,还有更多作为json深度的

您可以找到有关Querying Json here

的更多信息

答案 2 :(得分:0)

根据OOP和其他设计原则,具有相同属性的这种类型的结构不易维护。 如果您可以更改类和JSON结构,那么我建议您遵循以下示例结构。

[{
      cute : true, 
      feet : 4, 
      type : "dog"
      }, {
      cute : true, 
      feet : 2, 
      type : "bird"
 }]

我们可以使用一个Pet类对象列表,而不是使用Bird和Dog子类的类。

class Pet
{
    int Feet {get; set; }
    string Type { get; set; }
    bool Cute { get; set; }
}

现在在您希望读取它的方法中,您可以读取Json并返回要搜索的列表。

List<Pet> pets = ReadPetJson();
string Pet_Name = DummyPetName(); // Returns string 'Bird' or 'Dog' etc.
var matchedPet = pets.FirstOrDefault(x => 
x.Type.ToLower() == Pet_Name);
if (matchedPet != null)
   return matchedPet.Cute;