【问题标题】:Serializing and Deserializing dynamically using JSON in C#在 C# 中使用 JSON 动态序列化和反序列化
【发布时间】:2021-01-13 18:41:55
【问题描述】:

首先,我想我正在尝试动态地序列化和反序列化,而不是以编程方式。对不起,如果我在标题中写错了。

我是一名软件工程专业的学生,​​我正在尝试学习一些关于 JSON 的知识。我创建了一个类(我可能会将它用作我的项目的 .dll)来序列化和反序列化。

    public class JSONParser
    {
        public object JsonDeserialize(Type dataType, string filePath)
        {
            JsonSerializer jsonSerializer = new JsonSerializer();

            StreamReader sr = new StreamReader(filePath);
            JsonReader jsonReader = new JsonTextReader(sr);
            JObject obj = jsonSerializer.Deserialize(jsonReader) as JObject;

            jsonReader.Close();
            sr.Close();

            return obj.ToObject(dataType);
        }

        public void JsonSerialize(object data, string filePath)
        {
            JsonSerializer jsonSerializer = new JsonSerializer();

            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }

            StreamWriter sw = new StreamWriter(filePath);
            JsonWriter jsonWriter = new JsonTextWriter(sw);

            jsonWriter.Formatting = Formatting.Indented;
            jsonSerializer.Serialize(jsonWriter, data);

            jsonWriter.Close();
            sw.Close();
        }
    }

我这样称呼它:

                    Animal animal = new Animal
                    {
                        AnimalName = AnimalNameTextBox,
                        AnimalBreed = AnimalBreedTextBox,
                    };

                    AnimalList Animal = new AnimalList ();
                    JSONParser jsonParser = new JSONParser();

                    if (File.Exists(_animalFilePath))
                    {
                        Animal = jsonParser.JsonDeserialize(typeof(AnimalList), _animalFilePath) as AnimalList;
                    }

                    Animal.ListOfAnimals.Add(animal);

                    jsonParser.JsonSerialize(Animal, _animalFilePath);

这里是动物类:

    public class Animal
    {
        public string AnimalName { get; set; }
        public string AnimalBreed { get; set; }

        public Animal()
        {
        }

        public Animal(string AnimalName, string AnimalBreed)
        {
            this.AnimalName = AnimalName;
            this.AnimalBreed = AnimalBreed;
        }
    }

这里是 AnimalList 类:

    public class AnimalList 
    {
        public List<Animal> ListOfAnimals { get; set; }
        public Animal NewAnimal { get; set; }
        public string AnimalName { get; set; }
        public string AnimalBreed { get; set; }

        public AnimalList()
        {
            ListOfAnimals = new List<Animal>();
        }
    }

到目前为止效果很好。

我使用反序列化时得到的 JSON 对象

JObject obj = jsonSerializer.Deserialize(jsonReader) as JObject;

{{
  "ListOfAnimals": [
    {
      "AnimalName": "Doggie",
      "AnimalBreed": "Dog"
    }
  ],
  "NewAnimal": null,
  "AnimalName": null,
  "AnimalBreed": null
}}

但是,我觉得我不需要创建一个 AnimalList 类来执行此操作,但如果我不这样做,当我尝试反序列化时,JSON 不知道如何解释里面的信息JSON 文件。我无法弄清楚如何动态地告诉 JSON 它是一个动物列表。

这是使用此方法创建的序列化文件的内容

{
  "ListOfAnimals": [
    {
      "AnimalName": "Doggie",
      "AnimalBreed": "Dog"
    },
    {
      "AnimalName": "Gatito",
      "AnimalBreed": "Cat"
    }
  ],
  "NewAnimal": null,
  "AnimalName": null,
  "AnimalBreed": null
}

我尝试不使用 AnimalList 类(只是 Animal 的 List),它会创建这个文件

[
  {
    "AnimalName": "Doggie",
    "AnimalBreed": "Dog"
  }
]

所以,它会序列化它,但它不知道如何反序列化它(这个 JObject 将返回 null)。

JObject obj = jsonSerializer.Deserialize(jsonReader) as JObject;

我做错了什么? 抱歉,如果太长了;我尽量说清楚。

谢谢

【问题讨论】:

  • 它返回 null 因为你序列化了 dataAnimalList 实例),它会反序列化你试图转换为 JObject 的相同类型(不可能,因此 null )。考虑使用泛型Deserialize&lt;T&gt;,它将简单地调用 Json.net 的泛型方法。然后你可以简单地拨打Deserialize&lt;AnimalList&gt;()
  • 不不,我想我解释错了。如果我使用 AnimalList 类,一切都很好。问题是当我试图避免使用类 AnimalList 时,我只是创建了一个 List,以避免创建额外的类 AnimalList。我不知道,我认为这只是额外的代码行(而且 json 文件看起来不像我在其他任何地方都能看到的那样)。
  • 我会改写:要使您的 Deserialize 方法适用于任何事情,您需要将类型参数传递给它。如果你在编译时就知道类型,那么泛型是最方便的方法。
  • 如果你序列化List&lt;Animal&gt;,那么你必须使用Deserilize&lt;List&lt;Animal&gt;&gt;()反序列化它。请参阅this(我假设您使用的是 json.net)。
  • 我正在尝试;对不起,如果我太笨了。 public object JsonDeserialize&lt;T&gt;(Type dataType, string filePath) 调用自:List&lt;Animal&gt; Animal = jsonParser.JsonDeserialize&lt;List&lt;Animal&gt;&gt;(typeof(List&lt;Animal&gt;), _animalFilePath) as List&lt;Animal&gt;;该对象仍然返回 null。我想我把事情复杂化了。我是吗?

标签: c# json dynamic json-deserialization json-serialization


【解决方案1】:

感谢@Sinatr 的帮助。 这就是我在不使用充当 List 的类的情况下设法做到这一点的方法。

        public object JsonDeserialize<T>(string filePath)
        {
            String JSONtxt = File.ReadAllText(filePath);
            var obj = JsonConvert.DeserializeObject<T>(JSONtxt);

            return obj;
        }
        public object JsonDeserialize<T>(string filePath)
        {
            String JSONtxt = File.ReadAllText(filePath);
            var obj = JsonConvert.DeserializeObject<T>(JSONtxt);

            return obj;
        }

然后,这样称呼它:

保存到文件

                    Client client = new Client
                    {
                        ClientName = NameTextBox,
                        ClientAge = Convert.ToInt32(AgeTextBox),
                        ClientStreet = StreetTextBox,
                    };

                    List<Client> ClientList = new List<Client>();
                    JSONParser jsonParser = new JSONParser();    

                    //Check if File exists. If it does, deserialize the file and add the content to the List Client
                    if (File.Exists(_filePath))
                    {
                        ClientList = jsonParser.JsonDeserialize<List<Client>>(_filePath) as List<Client>;
                    }

                    ClientList.Add(client);
                
                    jsonParser.JsonSerialize<List<Client>>(ClientList, _filePath);

从文件加载:

            // First, check if file already exists
            if (!File.Exists(_filePath))
            {
                MessageBox.Show("The file is empty. Please, save some details before trying to load it.");
                return;
            }

            // If file doesn't exist
            else
            {
                JSONParser jsonParser = new JSONParser();
                List<Client> ClientList = jsonParser.JsonDeserialize<List<Client>>(_filePath) as List<Client>;
            }

我希望这可以帮助其他人。 再次感谢@Sinatr。

PS:如果有人认为我错了,或者有更好的方法,请告诉我。添加您的答案或写评论。谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-22
    • 2014-01-06
    • 1970-01-01
    • 2021-09-14
    • 2016-11-14
    • 1970-01-01
    • 2012-09-05
    • 2012-11-11
    相关资源
    最近更新 更多