Невозможно получить значение из вложенного JSON - PullRequest
0 голосов
/ 25 января 2019

Я десериализую объект JSON в класс, который я создал с помощью json2csharp. После десериализации я не могу получить доступ к вложенным значениям этого объекта. Я получаю следующую ошибку:

System.NullReferenceException: 'Ссылка на объект не установлена ​​для экземпляра объекта.'

Это класс, который я создал;

public class Ticker
{
    public List<object> error { get; set; }
    public Result result { get; set; }

    public class Result
    {
        public XXBTZCAD XBTCAD { get; set; }


        public class XXBTZCAD
        {
            public List<string> a { get; set; }
            public List<string> b { get; set; }
            public List<string> c { get; set; }
            public List<string> v { get; set; }
            public List<string> p { get; set; }
            public List<int> t { get; set; }
            public List<string> l { get; set; }
            public List<string> h { get; set; }
            public string o { get; set; }
        }
    }
}

Вот строка JSON на момент написания этой статьи:

{
  "error": [

  ],
  "result": {
 "XXBTZCAD": {
  "a": [
    "4776.10000",
    "8",
    "8.000"
  ],
  "b": [
    "4773.90000",
    "1",
    "1.000"
  ],
  "c": [
    "4776.20000",
    "0.02510294"
  ],
  "v": [
    "4.85183508",
    "61.15237421"
  ],
  "p": [
    "4775.02293",
    "4767.92898"
  ],
  "t": [
    126,
    608
  ],
  "l": [
    "4756.70000",
    "4720.60000"
  ],
  "h": [
    "4780.00000",
    "4783.30000"
  ],
  "o": "4776.40000"
 }
 }
}

Это код, который десериализует и пытается отобразить первое значение List a

    private async void GetKraken(object sender, RoutedEventArgs e)
    {
        var client = new RestClient();
        IRestResponse response;
        Ticker BTCCADTicker = new Ticker();
        client.BaseUrl = new Uri("https://api.kraken.com/0/public/Ticker?pair=XBTCAD");
        var request = new RestRequest();
        response = await client.ExecuteTaskAsync(request);
        BTCCADTicker = JsonConvert.DeserializeObject<Ticker>(response.Content);
        MessageBox.Show(BTCCADTicker.result.XBTCAD.a[0]);
    }

Я ожидаю увидеть возвращаемое значение около 4700, но вместо этого я получаю ошибку выше. Что дает? Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Я предлагаю скопировать ваш JSON и в Visual Studio:

Правка> Вставить специальный> Разобрать JSON как классы

public class Ticker
{
    public object[] error { get; set; }
    public Result result { get; set; }
}

public class Result
{
    public XXBTZCAD XXBTZCAD { get; set; }
}

public class XXBTZCAD
{
    public string[] a { get; set; }
    public string[] b { get; set; }
    public string[] c { get; set; }
    public string[] v { get; set; }
    public string[] p { get; set; }
    public int[] t { get; set; }
    public string[] l { get; set; }
    public string[] h { get; set; }
    public string o { get; set; }
}

, и вы можете использовать этот метод дляполучить результат:

public static async Task<string> GetKraken()
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.GetAsync("https://api.kraken.com/0/public/Ticker?pair=XBTCAD");
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();
    return responseBody;
}

, а затем использовать метод и преобразовать его для получения фактического объекта:

var ticker = JsonConvert.DeserializeObject<Ticker>(GetKraken().Result);
0 голосов
/ 25 января 2019

Вы не определили XXBTZCAD в своей модели.Вы назвали это XBTCAD по ошибке.Исправлено это выглядит так:

public class Ticker
{
    public List<object> error { get; set; }
    public Result result { get; set; }

    public class Result
    {
        public XXBTZCAD XXBTZCAD { get; set; }


        public class XXBTZCAD
        {
            public List<string> a { get; set; }
            public List<string> b { get; set; }
            public List<string> c { get; set; }
            public List<string> v { get; set; }
            public List<string> p { get; set; }
            public List<int> t { get; set; }
            public List<string> l { get; set; }
            public List<string> h { get; set; }
            public string o { get; set; }
        }
    }
}

Теперь я вижу, что это то же имя, что и вложенный класс.Я бы порекомендовал простое решение не вкладывать ваши классы:

public class Ticker
{
    public List<object> error { get; set; }
    public Result result { get; set; }
}

public class Result
{
    public XXBTZCAD XXBTZCAD { get; set; }
}



public class XXBTZCAD
{
    public List<string> a { get; set; }
    public List<string> b { get; set; }
    public List<string> c { get; set; }
    public List<string> v { get; set; }
    public List<string> p { get; set; }
    public List<int> t { get; set; }
    public List<string> l { get; set; }
    public List<string> h { get; set; }
    public string o { get; set; }
}

Если вы действительно хотите их вкладывать, просто переименуйте class XXBTZCAD в другое.Для десериализации важно имя свойства, а не имя типа.

...