Json. Net Десериализация списка c# объектов, вызывающих ошибку - PullRequest
0 голосов
/ 16 июня 2020

У меня есть список объектов в формате json ниже. Я хотел бы десериализовать, используя приведенный ниже код. Выдает ошибку «Невозможно преобразовать в объект». Я пробовал следующие три варианта, но не помогло. jsoninput - это IEnumerable<string>, преобразованный в json объект с использованием ToJson().

Ошибка: {"Error converting value \"{\"id\":\"11ef2c75-9a6d-4cef-8163-94daad4f8397\",\"name\":\"bracing\",\"lastName\":\"male\",\"profilePictureUrl\":null,\"smallUrl\":null,\"thumbnailUrl\":null,\"country\":null,\"isInvalid\":false,\"userType\":0,\"profilePrivacy\":1,\"chatPrivacy\":1,\"callPrivacy\":0}\" to type 'Api.Models.UserInfo'. Path '[0]', line 1, position 271."}

var requests1 = JsonConvert.DeserializeObject<UsersInfo>(jsoninput);
var requests2 = JsonConvert.DeserializeObject<IEnumerable<UserInfo>>(jsoninput);
var requests3 = JsonConvert.DeserializeObject<List<UserInfo>>(jsoninput);

//Below are my classes,
public class UsersInfo

{
    public List<UserInfo> UserInfoList { get; set; }
    public UsersInfo()
    {
        UserInfoList = new List<UserInfo>();
    }
}

public class UserInfo
{
    public string Id { set; get; }
    public string Name { set; get; }
    public string LastName { set; get; }
    public string ProfilePictureUrl { set; get; }
    public string SmallUrl { set; get; }
    public string ThumbnailUrl { get; set; }
    public string Country { set; get; }
    public bool IsInvalid { set; get; }
}

Ниже мой объект json,

["{\"id\":\"11ef2c75-9a6d-4cef-8163-94daad4f8397\",\"name\":\"bracing\",\"lastName\":\"male\",\"profilePictureUrl\":null,\"smallUrl\":null,\"thumbnailUrl\":null,\"country\":null,\"isInvalid\":false}","{\"id\":\"318c0885-2720-472c-ba9e-1d1e120bcf65\",\"name\":\"locomotives\",\"lastName\":\"riddles\",\"profilePictureUrl\":null,\"smallUrl\":null,\"thumbnailUrl\":null,\"country\":null,\"isInvalid\":false}"]

Цикл через отдельные элементы на входе json, и если я десериализую его, как показано ниже, он работает нормально. Но я хочу полностью десериализовать список. Примечание: jsoninput было IEnumerable<string> до того, как я преобразовал в json объект.

foreach (var re in jsoninput)
{
    var request0 = JsonConvert.DeserializeObject<UserInfo>(re);
}

1 Ответ

2 голосов
/ 16 июня 2020

Пожалуйста, посмотрите на эту скрипку: https://dotnetfiddle.net/XpjuL4

Это код:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

//Below are my classes,
public class UsersInfo 
{
    public List<UserInfo> UserInfoList { get; set; }
    public UsersInfo()
    {
        UserInfoList = new List<UserInfo>();
    }
}

public class UserInfo
{
    public string Id { set; get; }
    public string Name { set; get; }
    public string LastName { set; get; }
    public string ProfilePictureUrl { set; get; }
    public string SmallUrl { set; get; }
    public string ThumbnailUrl { get; set; }
    public string Country { set; get; }
    public bool IsInvalid { set; get; }
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        Option1();
        Option2();
    }

    public static void Option1(){
        string json = @"{""UserInfoList"":[
            {""id"":""11ef2c75 - 9a6d - 4cef - 8163 - 94daad4f8397"",""name"":""bracing"",""lastName"":""male"",""profilePictureUrl"":null,""smallUrl"":null,""thumbnailUrl"":null,""country"":null,""isInvalid"":false},
            { ""id"":""318c0885-2720-472c-ba9e-1d1e120bcf65"",""name"":""locomotives"",""lastName"":""riddles"",""profilePictureUrl"":null,""smallUrl"":null,""thumbnailUrl"":null,""country"":null,""isInvalid"":false}
        ]}";
        var obj = JsonConvert.DeserializeObject<UsersInfo>(json);
        obj.UserInfoList.ForEach(e => Console.WriteLine(e.Id));
    }

    public static void Option2(){
    string json = @"[
            {""id"":""11ef2c75 - 9a6d - 4cef - 8163 - 94daad4f8397"",""name"":""bracing"",""lastName"":""male"",""profilePictureUrl"":null,""smallUrl"":null,""thumbnailUrl"":null,""country"":null,""isInvalid"":false},
            { ""id"":""318c0885-2720-472c-ba9e-1d1e120bcf65"",""name"":""locomotives"",""lastName"":""riddles"",""profilePictureUrl"":null,""smallUrl"":null,""thumbnailUrl"":null,""country"":null,""isInvalid"":false}
        ]";
        var obj = JsonConvert.DeserializeObject<List<UserInfo>>(json);
        obj.ForEach(e => Console.WriteLine(e.Id));
    }
}

Оба работают и в основном очень близки к тому, что вы делаю. Вы можете либо сериализовать его как список (на основе вашего json, я думаю, что это самый близкий к вашему варианту использования, и это вариант 2).

Однако обратите особое внимание на JSON. Мне пришлось повторно проанализировать ваш JSON, чтобы он заработал (https://jsonformatter.org/json-parser - хороший сайт для этого). Для пояснения примера в C#, @ означает необработанную строку, а в необработанной строке кавычки экранируются двойными кавычками "".

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

EDIT Учитывая комментарий OP:

Спасибо Tu.ma за мысли. Другой метод возвращает IEnumerable, который представляет собой не что иное, как Dictionary.Where (x => x.Value == null) .Select (x => x.Key) .ToHashSet (). Значения в словаре: -> Key - String, Value - сериализованный объект UserInfo. Итак, в таком случае я должен десериализовать одну за другой? Если нет, я должен сериализовать весь список одним выстрелом? Я прав? - Raj 12 часов go

Проблема в способе создания списка UsersInfo. Результатом Dictionary<string,string>.Where(x => x.Value == null).Select(x => x.Key).ToHashSet() является набор строк, а не объектов, поэтому вам нужно сериализовать их одну за другой.

Если вас беспокоит линейность подхода, вы могли бы считать через него параллельно . Конечно, вам нужно оценить, подходит ли он для вашего приложения.

var userInfoStrings = Dictionary<string,string>.Where(x => x.Value == null).Select(x => x.Key).ToHashSet();

var UserInfoList = userInfoStrings.AsParallel().Select (u => JsonConvert.DeserializeObject<UsersInfo>(u)).ToList();
...