JSON反序列化用于多态结果

时间:2018-05-31 15:21:29

标签: c# json rest deserialization


我有以下问题让我疯狂找到合适的解决方案 我必须使用两个RESTful API,除了items结构之外,它们返回相同的结构。
让我举两个例子:

    {
"hasmoredata":true,
      "current_page": 1,
      "page_size": 20,
      "total_pages": 5,
      "items": [
          {
            "user_id": "1",
            "username": "carl",
            "first_name": "carl",
           }
      ]
    }

    {
"hasmoredata":true,
      "current_page": 1,
      "page_size": 10,
      "total_pages": 2,
      "items": [
          {
            "course_id": "10",
            "course_name": "Math",
            "duration": "3h",
           }
      ]
    }

我希望有两个类扩展一个收集公共属性的抽象类。像这样(在C#中):

 public abstract class CursorResult
    { 

        [JsonProperty("current_page")]
        public int CurrentPage { get; set; }

        [JsonProperty("page_size")]
        public int PageSize { get; set; }

        [JsonProperty("total_pages")]
        public int TotalPages { get; set; }

[JsonProperty("hasmoredata")]
            public bool HasMoreData{ get; set; }
        }

public class UsersList : CursorResult
    {
        [JsonProperty("items")]
        List<User> Users { get; set; }
    }

public class CoursesList : CursorResult
    {
        [JsonProperty("items")]
        List<Courses> Courses { get; set; }
    }

现在的问题是我必须编写一个收集整个结果的函数(所有项目页面)并将这些结果合并为一个:

private CursorResult GetEntireResult(string apiURL)
        {
            Cursor c = new Cursor(1, pageSize);

            CursorResult result = TryDeserializeCursorResult(CallRestFulAPI(apiURL + c.GetCursorParametersString, Method.GET));

            c.Hashcode = result.CursorHashCode;

            while (result.HasMoreData)
            {
                c.CurrentPage += 1;
                result.AddItems(TryDeserializeCursorResult(CallRestFulAPI(apiURL + c.ParametersString, Method.GET)));
            }

            return result;
        }

但我不知道如何根据API结果编写AddItem函数以添加用户或课程。

提前感谢您的帮助!

拉​​波

1 个答案:

答案 0 :(得分:1)

有几件事:

  1. 使用当前代码,假设您正在使用默认序列化程序,当您反序列化时,您不会捕获“项目”,因为您要反序列化为没有'items'属性的CursorResult定义。序列化程序不会自动了解派生类型。另外,我建议将UserList和CoursesList类重命名为UserCursorResult / CourseCursorResult。这些类不是列表,它们包含列表。

  2. 以下是区分json序列化(子)类型的代码:

            string yourJsonString = @"{ 'hasmoredata':true,'current_page': 
            1,'page_size': 20,'total_pages': 5,'items': [{'user_id': 
            '1','username': 'carl','first_name': 'carl'}]}";
    
            JSchemaGenerator generator = new JSchemaGenerator();
            JSchema userSchema = generator.Generate(typeof(UsersList));
            JSchema courseSchema = generator.Generate(typeof(CoursesList));
            JToken jObject = JObject.Parse(yourJsonString);
    
            if (jObject.IsValid(courseSchema))
            {
                CoursesList courseList = JsonConvert.DeserializeObject<CoursesList>(yourJsonString);
                //do stuff with CourseList
            }
            else if (jObject.IsValid(userSchema))
            {
                UsersList userList = JsonConvert.DeserializeObject<UsersList>(yourJsonString);
                //do stuff with UsersList
            }