динамический тип в свойстве класса - PullRequest
0 голосов
/ 05 февраля 2019

в методе GetInfo вернул Result в формате JSON следующим образом:

"Result": {
    "Id": 11975,
    "Email": null,
    "CellPhone": "123456789",
    "FirstName": "John",
    "LastName": "Rock",
    "Avatar": null,
    "Address": null,
},
"StatusCode": 200,
"Message": "success",
"Version": "API V1.1"

я могу десериализовать значение результата до

public class SignInResultResponse
{

    public SignInResponse Result { get; set; }
    public int StatusCode { get; set; }
    public string Message { get; set; }
    public string Version { get; set; }

}
public class SignInResponse
{

    public int Id { get; set; }
    public string Email { get; set; }
    public string CellPhone { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Avatar { get; set; }
    public string Address { get; set; }

}

в результате метода GetList JSON:

"Result": [
    {
        "Id": 42022,
        "Title": "User Title",
        "Avatar": null,
        "Rate": 0,
        "RateCount": 0,
        "Status": {
            "Id": 1,
            "Title": "Active"
        }
    }
],
"StatusCode": 200,
"Message": "profile is not complete",
"Version": "API V1.1"

как создать динамическое свойство Result в классе Response для любого типа класса?

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Вы можете использовать Generic Class и JToken вместе для получения десериализованных данных из вашего ответа

public class StandardResponse<T>
{
    public JToken Result { get; set; }
    public int StatusCode { get; set; }
    public string Message { get; set; }
    public string Version { get; set; }

    public List<T> _Result
    {
        get
        {
            if (Result.Type == JTokenType.Array)
            {
                List<T> signInResponses = new List<T>();
                signInResponses = Result.ToObject<List<T>>();
                return signInResponses;
            }
            else if (Result.Type == JTokenType.Object)
            {
                List<T> signInResponses = new List<T>();
                signInResponses.Add(Result.ToObject<T>());
                return signInResponses;
            }
            else
                return new List<T>();
        }
    }
}

В вышеприведенном классе свойство Result имеет тип JToken, что означает, что любой действительный json может бытьдесериализовать в этот тип.

И тогда свойство _Result имеет тип List<T>, где T - это любой ваш класс, для которого вы хотите десериализовать ваши данные ключа Result из json.

Если ваш Result ключ содержит данные типа

  • Объект, тогда _Result выдаст вам список одного объекта типа T.
  • Список, затем _Result выдаст вам список нескольких объектов типа T

Поэтому вам больше не нужно проверять вручную, содержит ли ключ Result данные типа объекта или массива.Свойство _Result сделает это за вас.

Использование:

var result = JsonConvert.DeserializeObject<StandardResponse<SignInResponse>>(json);

var signInResponses = result._Result;

Теперь вы можете использовать любой тип вашего класса как T какЯ использовал SignInResponse в приведенном выше коде.

0 голосов
/ 05 февраля 2019

Существует ключевое слово dynamic , и вы можете использовать его в качестве типа поля Result.Хотя, похоже, ваши два ответа должны быть довольно отдельными классами, которые могут наследоваться от одного Result класса, содержащего StatusCode , Message , Version .В ваших наследующих классах вы просто добавите Response поле определенного типа для соответствия ответу.

public abstract class Result
{
    public int StatusCode { get; set; }
    public string Message { get; set; }
    public string Version { get; set; }
}

public class SignInResult : Result
{
    public SignInResponse Response { get; set; }
}

public class ListResult : Result
{
    public IList<ListResponse> Response { get; set; }
}

В этом случае вы можете видеть, что поле Response всегда существует, но отличается по типу, поэтому выможет создать класс Result, например:

public abstract class Result<T>
{
    public T Response { get; set; }
    public int StatusCode { get; set; }
    public string Message { get; set; }
    public string Version { get; set; }
}

А затем просто использовать его при десериализации с правильным параметром типа.

...