如何将 JSON 反序列化为具有多个 List<T> 参数的 .NET 对象?
Posted
技术标签:
【中文标题】如何将 JSON 反序列化为具有多个 List<T> 参数的 .NET 对象?【英文标题】:How can I deserialize a JSON to a .NET object with several List<T> parameters? 【发布时间】:2022-01-23 20:42:36 【问题描述】:我正在使用 this library (FireSharp) 访问 Firebase。我检索了一个 json 作为 FirebaseResponse 的主体(基本上是状态和主体),效果很好,看起来像这样(所有测试数据):
"\"Cobros\":\"1001\":\"Estado\":\"Cobrado\",\"Repartidor\":124,\"1112\":\"Estado\":\"Pendiente\",\"Repartidor\":124,\"Pedidos\":\"1111\":\"Estado\":\"Entregado\",\"Repartidor\":123,\"Repartidores\":\"123\":\"ID android\":\"asdadada\",\"Terminal\":123,\"124\":\"ID Android\":\"dggrefawe\",\"Terminal\":124"
Firebase 结构看起来 like this,其后面带有一些参数。 我需要反序列化 Json 以将其嵌入到具有多个列表参数的对象中,一个用于 18500 后面的每个节点。我已经检查了this question,这是我到目前为止的代码:
public class cargaFirebase
[JsonProperty("Cobros")]
public List<documentoFirebase> carfb_cobros get; set;
[JsonProperty("Pedidos")]
public List<documentoFirebase> carfb_pedidos get; set;
[JsonProperty("Repartidores")]
public List<repartidorFirebase> carfb_repartidores get; set;
然后反序列化尝试...
FirebaseResponse resp = fbClient.Get(request);
cargaFirebase carga_res = JsonConvert.DeserializeObject<cargaFirebase>(resp.Body);
这给了我一个我无法理解的反序列化错误,没有真正进入 jsons 抱歉,谢谢!
Newtonsoft.Json.JsonSerializationException: 无法将当前 JSON 对象(例如 "name":"value")反序列化为类型 'System.Collections.Generic.List`1[Reparto_Android.Code.Helpers.FirebaseHelper+documentoFirebase ]' 因为 该类型需要一个 JSON 数组(例如 [1,2,3])才能正确反序列化。 要修复此错误,要么将 JSON 更改为 JSON 数组(例如 [1,2,3]),要么将反序列化类型更改为普通的 .NET 类型(例如,不是像整数这样的原始类型,而不是像这样的集合类型可以从 JSON 对象反序列化的数组或列表。 JsonObjectAttribute 也可以添加到类型中以强制它从 JSON 对象反序列化。 路径
【问题讨论】:
这些属性中没有一个是正确的。您没有 Cobros、Pedidos 或 Repartidores 的列表,它们都是单个对象 - 正如异常消息告诉您的那样:“要修复此错误,请将 JSON 更改为 JSON 数组(例如 [1,2,3])或更改反序列化类型,使其成为可以从 JSON 反序列化的普通 .NET 类型(例如,不是整数之类的原始类型,不是数组或列表之类的集合类型)对象。” 【参考方案1】:这段代码可以正常工作
cargaFirebase carga_res = JsonConvert.DeserializeObject<CargaFirebase>(resp.Body);
如果你使用这些类
public partial class CargaFirebase
[JsonProperty("Cobros")]
public Dictionary<string, Cobro> Cobros get; set;
[JsonProperty("Pedidos")]
public Pedidos Pedidos get; set;
[JsonProperty("Repartidores")]
public Dictionary<string, Repartidore> Repartidores get; set;
public partial class Cobro
[JsonProperty("Estado")]
public string Estado get; set;
[JsonProperty("Repartidor")]
public long Repartidor get; set;
public partial class Pedidos
[JsonProperty("1111")]
public Cobro The1111 get; set;
public partial class Repartidore
[JsonProperty("ID Android")]
public string IdAndroid get; set;
[JsonProperty("Terminal")]
public long Terminal get; set;
输出
"Cobros":
"1001":
"Estado": "Cobrado",
"Repartidor": 124
,
"1112":
"Estado": "Pendiente",
"Repartidor": 124
,
"Pedidos":
"1111":
"Estado": "Entregado",
"Repartidor": 123
,
"Repartidores":
"123":
"ID Android": "asdadada",
"Terminal": 123
,
"124":
"ID Android": "dggrefawe",
"Terminal": 124
【讨论】:
【参考方案2】:如果所有这些叶子名称,例如“1111”、“1001”、“1112”,都是动态生成的,而您想忽略它们,也许您可以尝试一些自定义的 json 转换器,如下所示:
public class CargaFirebase
[JsonConverter(typeof(DocumentoFirebaseConverter))]
public List<DocumentoFirebase> Cobros get; set;
[JsonConverter(typeof(DocumentoFirebaseConverter))]
public List<DocumentoFirebase> Pedidos get; set;
[JsonConverter(typeof(RepartidorFirebaseConverter))]
public List<RepartidorFirebase> Repartidores get; set;
public class DocumentoFirebase
public string Estado get; set;
public int Repartidor get; set;
public class RepartidorFirebase
[JsonProperty(PropertyName = "Id Android")]
public string Id_Android get; set;
public int Terminal get; set;
class DocumentoFirebaseConverter : JsonConverter
public override bool CanConvert(Type objectType)
return objectType == typeof(List<DocumentoFirebase>);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
var jObj = JObject.Load(reader);
List<DocumentoFirebase> docs = new List<DocumentoFirebase>();
foreach (JProperty prop in jObj.Properties())
var doc = prop.Value.ToObject<DocumentoFirebase>();
docs.Add(doc);
return docs;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
throw new NotImplementedException();
class RepartidorFirebaseConverter : JsonConverter
public override bool CanConvert(Type objectType)
return objectType == typeof(List<RepartidorFirebase>);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
var jObj = JObject.Load(reader);
List<RepartidorFirebase> repartidors = new List<RepartidorFirebase>();
foreach (JProperty prop in jObj.Properties())
var repartidor = prop.Value.ToObject<RepartidorFirebase>();
repartidors.Add(repartidor);
return repartidors;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
throw new NotImplementedException();
然后你可以尝试像之前那样解析原始 json:
cargaFirebase carga_res = JsonConvert.DeserializeObject<CargaFirebase>(resp.Body);
【讨论】:
以上是关于如何将 JSON 反序列化为具有多个 List<T> 参数的 .NET 对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何将具有嵌套属性的 JSON 对象反序列化为 Symfony 实体?
JSON.Net - 无法将当前 json 对象(例如 "name":"value")反序列化为类型 'system.collections.generic.l
如何将具有不同值的相同 JSON 对象反序列化为 java 类