Serialize and deserialize JSON object from separate classes without need to have stand-alone class?

冷暖自知 提交于 2020-01-06 06:35:21

问题


Is it possible to form an object from two classes and then serialize it to JSON, and when deserialize it back be able to get those two objects. say I have: an object of Student and a List<Course> is it possible to combine these two objects in one JSON object. I need this because building up a class for every JSON object would be very exhausting in the project I'm working on!


回答1:


Is it possible to form an object from two classes and then serialize it to JSON

Yes it is possible to do this just use Merge from JObject

for example here is an example

   class  Student
    {
        public string Name { get; set; }
    }

    class Course
    {
        public string Title { get; set; } 
    }

         var std = new Student() {Name = "foo"};
        var lstCours = new List<Course>() { new Course(){Title = "math"}};
        var stdJson = JsonConvert.SerializeObject(new {student=std});
        var lstCoursJson = JsonConvert.SerializeObject( new{Cours= lstCours});  
        JObject jObjectStd = JObject.Parse(stdJson);
        JObject jObjectLstCours = JObject.Parse(lstCoursJson);
        jObjectStd.Merge(jObjectLstCours,new JsonMergeSettings(){MergeArrayHandling = MergeArrayHandling.Concat}); 
        Console.WriteLine(jObjectStd.ToString());

here what you get as a merge

{
  "student": {
    "Name": "foo"
  },
  "Cours": [
    {
      "Title": "math"
    }
  ]
}

to deserialize this is pretty simple with JSON.net

var stdParsed = JObject.Parse(json).Property("student").Value.ToString();
             var lstCoursParsed = JObject.Parse(json).Property("Cours").Value.ToString();
            var stdDes = JsonConvert.DeserializeObject<Student>(stdParsed);
            var lstCoursDes = JsonConvert.DeserializeObject<List<Course>>(lstCoursParsed); 



回答2:


Yes, this is possible, and is actually very straightforward to do.

Say you have your two objects like this:

var student = new Student { Name = "Joe Schmoe" };

var courses = new List<Course>
{
    new Course { Title = "Underwater Basket Weaving 101" },
    new Course { Title = "History of Pancakes 102" }
};

On the serializing side, just use an anonymous object to combine your objects together and then serialize that:

var anon = new { Student = student, Courses = courses };

var json = JsonConvert.SerializeObject(anon, Formatting.Indented);

Here is the JSON you would get:

{
  "Student": {
    "Name": "Joe Schmoe"
  },
  "Courses": [
    {
      "Title": "Underwater Basket Weaving 101"
    },
    {
      "Title": "History of Pancakes 102"
    }
  ]
}

You can combine as many objects together as you need to in this way. On the flip side, you can deserialize to a dynamic variable (which is a JObject behind the scenes) and then recreate your original strongly-typed objects from it using ToObject<T>().

dynamic obj = JsonConvert.DeserializeObject(json);
var student = obj.Student.ToObject<Student>();
var courses = obj.Courses.ToObject<List<Course>>();

Round-trip demo: https://dotnetfiddle.net/OKJBg2

Alternatively you can use deserialize-by-example to deserialize back to an anonymous object if you don't like the dynamic variable / JObject idea. To do that, you first create an empty anonymous object in the same shape as the JSON to use as a "template" and then pass it along with the JSON to JsonConvert.DeserializeAnonymousType:

var template = new { Student = new Student(), Courses = new List<Course>() };
var anon = JsonConvert.DeserializeAnonymousType(json, template);

Student student = anon.Student;
List<Course> courses = anon.Courses;

Demo: https://dotnetfiddle.net/Inz0r8




回答3:


Serialize a KeyValuePair<Student, List<Course>> and deserialize to the KeyValuePair again.

var student = ...;
var courses = ...;

var json = JsonConvert.SerializeObject(new KeyValuePair<Student, List<Course>>(student, courses));

Then, deserialize it this way:

var pair = JsonConvert.DeserializeObject<KeyValuePair<Student, List<Course>>>(json);
var student = pair.Key;
var courses = pair.Value;

This is a workaround, but it's easy to understand, and very easy to use (compared to JObject or a class to combine them).




回答4:


Just Create new Class which has those 2 objects like this

public class StudentWithCours
{
    public Student student { get; set; }

    public List<Course> course { get; set; }
}

after that you can serialize/deserialize the class exemplar like this

.......

StudentWithCours myObject = new StudentWithCours();
//your some logic here]
var serilizedObject = JsonConvert.SerializeObject(myObject);
var deserilizedObject =  JsonConvert.DeserializeObject<StudentWithCours>(serilizedObject);



回答5:


It is. This one-liner depends on the Newtonsoft NuGet package, which is popular and better than the default serializer.

var myObject = ...;
Newtonsoft.Json.JsonConvert.SerializeObject(myObject);

Documentation: Serializing and Deserializing JSON

Other possibility:

You could use the JavaScriptSerializer class (add reference to System.Web.Extensions):

using System.Web.Script.Serialization;

var json = new JavaScriptSerializer().Serialize(obj);

Other options are available here, where you can find above two answers, along with many others.

Piece of code:

public class Student
{
    public string Name { get; set; }
    public List<Course> Courses { get; set; } = new List<Course>();

    public class Course
    {
        public string Name { get; set; }
        public string Code { get; set; }
    }
}

var student = new Student
{
    Name = "Jack",
    Courses = new List<Student.Course>
    {
        new Student.Course() {Name = "MATH", Code = "MA"},
        new Student.Course() {Name = "Science", Code = "SC"}
    }
};
var str = JsonConvert.SerializeObject(student);
var studentDeserialized = JsonConvert.DeserializeObject<Student>(str);

Try it out for yourself



来源:https://stackoverflow.com/questions/45326898/serialize-and-deserialize-json-object-from-separate-classes-without-need-to-have

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!