Невозможно прочитать JSON из Web API в C # - PullRequest
0 голосов
/ 31 октября 2018

Невозможно прочитать значение webapi в объект списка. Пожалуйста, посмотрите значение скриншота по ссылке http://prntscr.com/lcmw7q.

Ошибка Newtonsoft.Json.JsonSerializationException: 'Невозможно десериализовать текущий объект JSON (например, {"name": "value"}) в тип' System.Collections.Generic.List`1 [StudentProfileClient .StudentInfo] 'потому что для корректной десериализации типу требуется массив JSON (например, [1,2,3]). Чтобы исправить эту ошибку, либо измените JSON на массив JSON (например, [1,2,3]), либо измените десериализованный тип так, чтобы это был нормальный тип .NET (например, не примитивный тип, например, целое число, а не тип коллекции, например, массив или список), которые можно десериализовать из объекта JSON. JsonObjectAttribute также можно добавить к типу, чтобы заставить его десериализоваться из объекта JSON. Путь «данные», строка 2, позиция 10.

class StudentInfo
    {     




        public string cellPhone { get; set; }

        public string gender { get; set; }

        public string dateOfBirth { get; set; }
    }

 class RootClass
    {

        public int TotalCount { get; set; }
        public List<StudentInfo> stdinfo { get; set; }


    }
    static async Task GetData()
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://203.81.70.102:8092/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response;

                response = await client.GetAsync("control/qZkNkcGgWq6PiVbJzQ2=/student-profiles");

                if (response.IsSuccessStatusCode)
                {
                    List<StudentInfo> RootClass = new List<StudentInfo>();
                    RootClass = await response.Content.ReadAsAsync<List<StudentInfo>>();

                }

            }
        }

Ответы [ 5 ]

0 голосов
/ 31 октября 2018

простое решение, вам нужна обертка

Как это выглядит на практике? Это просто означает, что API, которые возвращают списки объектов, обертывают список в объект верхнего уровня. Например, предположим, что в вашем API есть тип данных Person. Если вы ПОЛУЧАЕТЕ одного человека, вы можете получить следующий ответ JSON:

{ "name": "John Smith" }

Пока все хорошо. Но что, если вы хотите список вместо одного? Наиболее интуитивный способ может быть следующим:

[{"name": "John Smith"}, {"name": "Jane Smith"}]

Но именно этой ситуации нам следует избегать. В результате нам нужно используйте объект верхнего уровня для списков, подобных этому, с одним свойством данных:

{"data": [{"name": "John Smith"}, {"name": "Jane Smith"}]}

так .....

Class Students{
public List<StudentInfo> roots{get;set;}

}

оставь себе класс учеников, добавь моих учеников и десериализуй к этому;

0 голосов
/ 31 октября 2018

1) Используя JObject в Newtonsoft.json.

Введите приведенную ниже команду в консоли диспетчера пакетов.

Install-Package Newtonsoft.Json

if (response.IsSuccessStatusCode)
{
    string json = await response.Content.ReadAsStringAsync();

    JObject jObject = JObject.Parse(json);

    List<StudentInfo> studentInfos = jObject["data"].ToObject<List<StudentInfo>>();
}

Выход:

enter image description here


2) Без использования Newtonsoft.json.

Введите приведенную ниже команду в консоли диспетчера пакетов.

Install-Package Microsoft.AspNet.WebApi.Client

if (response.IsSuccessStatusCode)
{
    RootClass rootClass = await response.Content.ReadAsAsync<RootClass>();

    List<StudentInfo> studentInfos = rootClass.data;
}

Выход:

enter image description here

Так что ваши занятия будут

public class StudentInfo
{
    public int sl { get; set; }
    public string studentId { get; set; }
    public string studentName { get; set; }
    public string school { get; set; }
    public string program { get; set; }
    public string fatherName { get; set; }
    public string motherName { get; set; }
    public string cellPhone { get; set; }
    public string gender { get; set; }
    public string dateOfBirth { get; set; }
}

public class RootClass
{
    public List<StudentInfo> data { get; set; }
    public string message { get; set; }
    public int total { get; set; }
}
0 голосов
/ 31 октября 2018

Вместо объявления RootClass в качестве списка, используйте:

var RootClass = ожидание ответа. Content.ReadAsAsync ()

Поместите точку останова в строку и проверьте Тип , который возвращается из API. Так как var примет все что угодно, вы можете проверить ответ. В основном ваша ошибка говорит о том, что вы пытаетесь CAST к недопустимому типу, поэтому десериализация не работает должным образом.

Кажется, возвращаемый объект - это массив, может быть, вам нужно получить массив и преобразовать его в список, или даже это совершенно другой объект, чем тот, который вы ожидаете, иметь другие свойства и т. Д ...

Лучший способ решить -> Отладка и убедитесь, что вы используете правильный тип для десериализации

0 голосов
/ 31 октября 2018

Итак, у вас есть класс с именем RootClass. И у вас есть класс с именем StudentInfo.

Кого вы ожидаете получить? Кажется, вы получаете что-то совершенно другое. Как я вижу здесь, https://prnt.sc/lcnlho, вы должны создать новый класс (или изменить структуру RootClass), который будет выглядеть следующим образом

 class ResponseContainer
    {
        public List<StudentInfo> data { get; set; }
    }

И вместо десериализации прямо в List, вы должны десериализовать в этот класс ResponseContainer:

var response = await response.Content.ReadAsAsync<ResponseContainer>();

p.s. Если вы хотите использовать свой RootClass, вам следует либо переименовать свойство stdinfo в «data», либо добавить атрибут JsonProperty, например:

 class RootClass
    {
        public int TotalCount { get; set; }

        [JsonProperty(PropertyName = "data")]
        public List<StudentInfo> stdinfo { get; set; }
    }
0 голосов
/ 31 октября 2018

Вы не можете напрямую десериализовать из своего ответа API, используя JsonConvert.DeserializeObject. -

 JObject jsonResponse = JObject.Parse(jsonString);
    JObject objResponse = (JObject)jsonResponse["response"];
    Dictionary<string, JArray> _Data = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, JArray>>(objResponse.ToString());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...