【问题标题】:JSON deserialization for polymorphic results多态结果的 JSON 反序列化
【发布时间】:2018-05-31 15:21:28
【问题描述】:


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

    {
"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;
        }

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

提前感谢您的帮助!

拉波

【问题讨论】:

    标签: c# json rest deserialization


    【解决方案1】:

    有几点:

      1234563定义。序列化程序不会自动知道派生类型。我还建议将 UserList 和 CoursesList 类重命名为 UserCursorResult/CourseCursorResult。这些类不是列表,它们包含列表。
    1. 这是区分 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
              }
      

    【讨论】:

    • 另外,您需要 Newtonsoft.Json.Schema 才能使用 JSchemaGenerator。
    • 非常感谢 Yuli,这对我帮助很大!但是如何在不使用 if case 的情况下概括 GetEntireResult 函数?提前谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多