Невозможно десериализовать текущий массив JSON (например, [1,2,3])

Я пытаюсь прочитать мой результат JSON.

Вот мой RootObject

public class RootObject
{
public int id { get; set; }
public bool is_default { get; set; }
public string name { get; set; }
public int quantity { get; set; }
public string stock { get; set; }
public string unit_cost { get; set; }
}

Вот мой результат JSON

[{"id": 3636, "is_default": true, "name": "Unit", "quantity": 1, "stock": "100000.00", "unit_cost": "0"}, {"id": 4592, "is_default": false, "name": "Bundle", "quantity": 5, "stock": "100000.00", "unit_cost": "0"}]

Вот мой код для чтения результата

     public static RootObject GetItems(string user, string key, Int32 tid, Int32 pid)
    {
        // Customize URL according to geo location parameters
        var url = string.Format(uniqueItemUrl, user, key, tid, pid);

        // Syncronious Consumption
        var syncClient = new WebClient();

        var content = syncClient.DownloadString(url);

        return JsonConvert.DeserializeObject<RootObject>(content);

    }

Но у меня проблема с этой ошибкой:

Невозможно десериализовать текущий массив JSON (например, [1,2,3]) в тип 'avaris_cash_salepoint.BL.UniqueItemDataRootObject', потому что тип требуется объект JSON (например, { "name": "value" }) для десериализации правильно. Чтобы исправить эту ошибку, либо измените JSON на объект JSON (например, { "name": "value" }) или изменить десериализованный тип на массив или тип, реализующий интерфейс коллекции (например, ICollection, IList), как List, который можно десериализовать из массива JSON. JsonArrayAttribute также можно добавить к типу, чтобы заставить его десериализуем из массива JSON. Путь '', строка 1, позиция 1.

в этой строке:   return JsonConvert.DeserializeObject(content);

Любая помощь для исправления этой ошибки?

Ответ 1

Я думаю, что проблема, с которой вы сталкиваетесь, заключается в том, что ваш JSON - это список объектов, когда он входит, и он напрямую не связан с вашим корневым классом.

var content будет выглядеть примерно так (предположим):

[
  {
    "id": 3636,
    "is_default": true,
    "name": "Unit",
    "quantity": 1,
    "stock": "100000.00",
    "unit_cost": "0"
  },
  {
    "id": 4592,
    "is_default": false,
    "name": "Bundle",
    "quantity": 5,
    "stock": "100000.00",
    "unit_cost": "0"
  }
]

Примечание: используйте http://jsonviewer.stack.hu/ для форматирования JSON.

Итак, если вы попробуете следующее, он должен работать:

  public static List<RootObject> GetItems(string user, string key, Int32 tid, Int32 pid)
    {
        // Customize URL according to geo location parameters
        var url = string.Format(uniqueItemUrl, user, key, tid, pid);

        // Syncronious Consumption
        var syncClient = new WebClient();

        var content = syncClient.DownloadString(url);

        return JsonConvert.DeserializeObject<List<RootObject>>(content);

    }

Вам нужно будет повторить итерацию, если вы не хотите возвращать список RootObject.


Я пошел дальше и протестировал это в приложении консоли, отлично работал.

enter image description here

Ответ 2

Это потому, что json, который вы получаете, представляет собой массив вашего класса RootObject, а не один экземпляр, измените ваш DeserialiseObject<RootObject> на что-то вроде DeserialiseObject<RootObject[]> (не проверено).

Затем вам придется либо изменить метод, чтобы вернуть коллекцию RootObject, либо выполнить некоторую дальнейшую обработку десериализованного объекта, чтобы вернуть один экземпляр.

Если вы посмотрите на форматированную версию ответа, который вы указали:

[
   {
      "id":3636,
      "is_default":true,
      "name":"Unit",
      "quantity":1,
      "stock":"100000.00",
      "unit_cost":"0"
   },
   {
      "id":4592,
      "is_default":false,
      "name":"Bundle",
      "quantity":5,
      "stock":"100000.00",
      "unit_cost":"0"
   }
]

Здесь вы можете увидеть два экземпляра.

Ответ 3

Вы можете использовать это, чтобы решить свою проблему:

private async void btn_Go_Click(object sender, RoutedEventArgs e)
{
    HttpClient webClient = new HttpClient();
    Uri uri = new Uri("http://www.school-link.net/webservice/get_student/?id=" + txtVCode.Text);
    HttpResponseMessage response = await webClient.GetAsync(uri);
    var jsonString = await response.Content.ReadAsStringAsync();
    var _Data = JsonConvert.DeserializeObject <List<Student>>(jsonString);
    foreach (Student Student in _Data)
    {
        tb1.Text = Student.student_name;
    }
}

Ответ 4

У вас есть массив, преобразуйте его в объект, например:

: [{ "id": 3636, "is_default": true, "name": "Unit", "количество": 1, "stock": "100000.00", "unit_cost": "0" }, { "id": 4592, "is_default": false, "name": "Bundle", "quantity": 5, "stock": "100000.00", "unit_cost": "0" }]

Ответ 5

Это может быть Ты

Прежде чем пытаться использовать ваш объект json с другим объектом, просто убедитесь, что API-интерфейс возвращает сырой json через браузер api/rootobject. В моем случае я обнаружил, что основной поставщик данных mssqlserver не работает, и выдал неисследованное исключение!

так просто, как, что :)

Ответ 6


  Чтобы прочитать более одного json tip (array, attribute), я сделал следующее.


var jVariable = JsonConvert.DeserializeObject<YourCommentaryClass>(jsonVariableContent);

изменить на

var jVariable = JsonConvert.DeserializeObject <List<YourCommentaryClass>>(jsonVariableContent);

Потому что вы не можете увидеть все биты в методе, используемом в foreach петля. Пример цикла foreach

foreach (jsonDonanimSimple Variable in jVariable)
                {    
                    debugOutput(jVariable.Id.ToString());
                    debugOutput(jVariable.Header.ToString());
                    debugOutput(jVariable.Content.ToString());
                }

Я также получил ошибку в этом цикле и изменил ее следующим образом.

foreach (jsonDonanimSimple Variable in jVariable)
                    {    
                        debugOutput(Variable.Id.ToString());
                        debugOutput(Variable.Header.ToString());
                        debugOutput(Variable.Content.ToString());
                    }