将列表<MyClass>转换为 JSON 失败



我正试图将我的对象列表转换为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,并得到一个异常,消息如下:无法将Newtonsoft.Json.Linq.J值添加到Newtonsoft.Json.Linq.JObject。

我做错了什么?

当您想序列化为字符串时,请执行以下操作:

var jsonString = JsonConvert.SerializeObject(list);

要转换回,请执行以下操作:

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

由于您序列化了一个List,所以它是一个数组,不能与JObject一起使用。我建议使用更通用的JToken来处理所有情况。如果必须以当前形式使用它,请使用JArray

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

基于我对OP的转换,希望能够将数组添加到现有对象中。有几种方法可以做到这一点,但我倾向于总是回到dynamic路线。

假设我们有一个看起来像这样的对象:

{
"hello":"world"
}

我们想添加一个数组作为属性hello的同级,所以它看起来像这样:

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

我们可以通过将原始模型转换为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);

您可以在这里使用任何您想要的模型,甚至是具体的模型(不仅仅是匿名对象(。我们向它添加了一个数组,然后将其序列化。现在看起来就像是我们想要的结果。

不能将JValueJArray或另一个JObject直接放入JObject;您需要将其放入一个JProperty(它有一个名称(中,并将添加到JObject中。这就是为什么你会看到错误的原因。此外,在将列表添加到JProperty之前,您应该使用JArray.FromObject将其转换为JArray。如果您使用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

最新更新