Создание унаследованных объектов ответа - PullRequest
0 голосов
/ 30 августа 2018

Я пишу некоторую интеграцию со сторонней платформой электронного обучения, которая возвращает различные ответы в разных схемах в зависимости от функции моего спокойного вызова API. Поскольку эти ответы возвращаются в нескольких разных схемах, я пытаюсь создать серию классов объектов ответа, которые наследуют базовый класс объекта Response, который будет содержать общие разделы JSON (также называемые «данные» и «сообщение») и разрешать каждый отдельный объект ответа должен быть переопределен или иметь дополнительные члены / классы на основе возвращаемого ответа.

Вот несколько примеров того, как схемы могут отличаться.

Возвращение создания класса:

{
  "data": [
    {
      "row_index": 0,
      "success": true,
      "message": "string"
    }
  ]
}

Возвращение создания пользователя:

{
  "data": [
    {
      "message": [
        {
          "id": "string",
          "message": "string"
        }
      ],
      "success": true,
      "user_id": 0
    }
  ]
}

Как видите, разные ответы имеют разные схемы. Создание класса возвращает только элемент message в объекте данных, а создание пользователя полностью имеет отдельный объект message.

Поскольку у меня не может быть класса с именем data в каждом объекте из-за неоднозначности, я думаю, что мне нужно создать базовый объект ответа, который содержит общие члены и позволяет мне переопределять или добавлять на лету как необходимо.

Я пытался создать базовый класс:

public class BaseResponse
{
    public List<Data> data;
    public class Data
    {
        public bool success { set; get; }
    }
}

а также пример производного класса:

public class ClassroomResponse : BaseResponse
{
    public class Data
    {
        public int row_index { get; set; }            
        public string message { get; set; }   
    }
}

Я не уверен, возможно ли это только с функциями, а не с классами, как я пытаюсь сделать выше? Есть ли способ добавить дополнительные члены к производному объекту (row_index и message не являются членами всех ответов, поэтому я хотел бы иметь возможность получать их по мере необходимости)

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Я пойду по маршруту дженериков

Допустим, у нас есть ответ на Класс создание как

public class ClassResponseObject {
    public int row_index { get; set; }
    public bool success { get; set; }
    public string message { get; set; };
}

и для пользователя создания:

public class UserResponseObject {
    public int user_id { get; set; }
    public bool success { get; set; }
    public MessageResponseObject message { get; set; };
}

и для сообщения

public class MessageResponseObject {
    public string id { get; set; }
    public string message { get; set; };
}

увидев приведенный выше код, мы можем обнаружить, что у нас есть общее свойство успеха в обоих ответах, поэтому давайте создадим базовый класс с этим свойством и наследуем эти классы с этим.

public class BaseResponseObject {
    public bool success { get; set; }
}

public class ClassResponseObject : BaseResponseObject {
    public int row_index { get; set; }
    public string message { get; set; };
}

public class UserResponseObject : BaseResponseObject {
    public int user_id { get; set; }
    public MessageResponseObject message { get; set; };
}

в этот момент мы видим еще одно общее свойство - message, но оба имеют разные типы. Это можно решить с помощью дженериков. Я рассматриваю, что может быть больше типов для свойства сообщения ответа, но оно должно работать в любом случае.

для этого давайте изменим наш BaseResponseObject и переместим туда свойство сообщения

public class BaseResponseObject<TMessage> {
    public bool success { get; set; }
    public TMessage message { get; set; }
}

поэтому наши объекты ответа станут примерно такими:

public class ClassResponseObject : BaseResponseObject<String> {
    public int row_index { get; set; }
}

public class UserResponseObject : BaseResponseObject<MessageResponseObject> {
    public int user_id { get; set; }
}

в качестве последнего шага нам нужно определить последний класс для фактического ответа

public class APIResponse<TResponse> {
    public List<TResponse> data { get; set; }
}

теперь, когда вы захватываете ответ для создания Class , вы можете просто захватить его в

APIResponse<ClassResponseObject>

аналогично для User создание, захватить его в

APIResponse<UserResponseObject>

Надеюсь, это поможет.

0 голосов
/ 30 августа 2018

Вы можете создать отдельные отдельные классы для каждого типа, что может быть правильным вариантом здесь, в зависимости от других вариантов, которые вы не показывали. Или вы можете использовать дженерики. Есть несколько способов сделать это, но вот один из способов, которым вы можете это сделать.

Базовый класс для общего ответа:

public abstract class Response<TData>
{
    [JsonProperty("data")]
    public TData Data { get; set; }
}

Базовый класс для объектов данных:

public abstract class BaseData<TMessage>
{
    [JsonProperty("success")]
    public bool Success { get; set; }
    [JsonProperty("message")]
    public TMessage Message { get; set; }
}

Тип ответа для создания класса:

public class ClassData : BaseData<string>
{
    [JsonProperty("row_index")]
    public int RowIndex { get; set; }
}

Типы ответов для создания пользователя:

public class UserData : BaseData<UserMessage>
{
    [JsonProperty("user_id")]
    public int UserId { get; set; }
}

public class UserMessage
{
    [JsonProperty("id")]
    public int Id { get; set; }
    [JsonProperty("message")]
    public string Message { get; set; }
}

И, наконец, общие типы ответов:

public class ClassResponse : Response<ClassData>
{ }

public class UserResponse : Response<UserData>
{ }

И теперь вы можете использовать объекты, как обычно:

var classData = new ClassResponse {Data = new ClassData {Message = ""}};
var classJson = JsonConvert.SerializeObject(classData);

var userData = new UserResponse {Data = new UserData {Message = new UserMessage {Message = ""}}};
var userJson = JsonConvert.SerializeObject(userData);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...