Преобразование списка <MyClass>в JSON не выполняется - PullRequest
0 голосов
/ 04 августа 2020

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

Мой класс для объектов в списке:

public class BriefResponseTestingDto
{
    public Guid GrantId { get; set; }
    public string GrantName { get; set; }
}

Мой код сериализации списка в JSON:

List<BriefResponseTestingDto> list = new List<BriefResponseTestingDto>();
list.Add(new BriefResponseTestingDto() { GrantId = new Guid(), GrantName = "Name1"});
list.Add(new BriefResponseTestingDto() { GrantId = new Guid(), GrantName = "Name2"});
list.Add(new BriefResponseTestingDto() { GrantId = new Guid(), GrantName = "Name3"});

dataAsJobject = new JObject(JsonConvert.SerializeObject(list));

После сериализации я пытаюсь преобразовать строку в JObject, и я получить исключение с сообщением: Can not add Newtonsoft. Json .Linq.JValue to Newtonsoft. Json .Linq.JObject.

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 04 августа 2020

Если вы хотите сериализовать в строку, сделайте следующее:

var jsonString = JsonConvert.SerializeObject(list);

Чтобы преобразовать обратно, сделайте следующее:

var myList = JsonConvert.DeserializeObject<List<BriefResponseTestingDto>>(jsonString);

Поскольку вы сериализовали List, это массив и он не будет работать с JObject. Я бы предложил еще более общий c JToken, который обрабатывает все случаи. Если вы должны работать с ним в текущем виде, используйте JArray.

var myjObj = JsonConvert.DeserializeObject<JArray>(jsonString);

Основываясь на моем преобразовании с OP, я хочу иметь возможность добавлять массив к существующему объекту. Есть несколько способов сделать это, но я всегда возвращаюсь к маршруту dynamic.

Допустим, у нас есть объект, который выглядит так:

{
    "hello":"world"
}

и мы хотим добавить массив в качестве родственника к свойству hello, чтобы он выглядел так:

{
    "hello":"world",
    "myArray":[1,2,3,4,5]
}

Мы можем выполнить sh это, взяв исходную модель и преобразовав ее в dynamic. Поскольку мы тесно связаны с Newtonsoft, я собираюсь воспользоваться этим, позволив этой библиотеке делать тяжелую работу.

Вот метод преобразования объекта в тип ExpandoObject dynamic который позволяет вам делать некоторые довольно изящные вещи:

public static dynamic ConvertObjectToExpandoObject(object obj)
{
    using (var ms = new MemoryStream())
    {
        using (var sw = new StreamWriter(ms, Encoding.UTF8, 1024, leaveOpen: true))
        using (var jtw = new JsonTextWriter(sw))
        {
            new JsonSerializer().Serialize(jtw, obj);
        }
        ms.Position = 0;
        using (var sr = new StreamReader(ms))
        using (var jtr = new JsonTextReader(sr))
        {
            return JsonSerializer.CreateDefault(new JsonSerializerSettings
            {
                Converters = { new ExpandoObjectConverter() }
            }).Deserialize<ExpandoObject>(jtr);
        }
    }
}

Теперь, когда это dynamic и он понимает семантику ExpandoObject, мы можем добавить к нему любое свойство как любой тип:

var myDynamic = ConvertObjectToExpandoObject(new { hello = "world" });
myDynamic.myArray = new int[] { 1, 2, 3, 4, 5 };
var jsonString = JsonConvert.SerializeObject(myDynamic);

Здесь вы можете использовать любую модель, которую хотите, даже конкретные модели (а не только анонимный объект). Мы добавили к нему массив, а затем снова сериализовали его. Теперь он будет выглядеть так, как мы хотели.

0 голосов
/ 04 августа 2020

Вы не можете напрямую поместить JValue, JArray или другой JObject в JObject; вам нужно поместить его в JProperty (у которого есть имя) и добавить , что к JObject. Вот почему вы получаете ошибку, которую видите. Кроме того, вы должны использовать JArray.FromObject, чтобы преобразовать ваш список в JArray, прежде чем добавлять его в JProperty. Если вы используете SerializeObject(), вместо этого вы получите строковое значение, которое вам здесь не нужно. См. Может Json. Net обрабатывать список ? для более подробного объяснения этого.

Итак, у вас будет:

var dataAsJobject = new JObject(new JProperty("data", JArray.FromObject(list)));
var json = dataAsJobject.ToString();

Fiddle: https://dotnetfiddle.net/eYMLVV

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

var anon = new { data = list };
var json = JsonConvert.SerializeObject(anon, Formatting.Indented);

Fiddle: https://dotnetfiddle.net/BGxvwf

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...