我尝试使用一个 API,该 API 将以下示例结构用于返回的 json
[
{
"customer":{
"first_name":"Test",
"last_name":"Account",
"email":"[email protected]",
"organization":"",
"reference":null,
"id":3545134,
"created_at":"2013-08-06T15:51:15-04:00",
"updated_at":"2013-08-06T15:51:15-04:00",
"address":"",
"address_2":"",
"city":"",
"state":"",
"zip":"",
"country":"",
"phone":""
}
},
{
"customer":{
"first_name":"Test",
"last_name":"Account2",
"email":"[email protected]",
"organization":"",
"reference":null,
"id":3570462,
"created_at":"2013-08-12T11:54:58-04:00",
"updated_at":"2013-08-12T11:54:58-04:00",
"address":"",
"address_2":"",
"city":"",
"state":"",
"zip":"",
"country":"",
"phone":""
}
}
]
JSON.net 可以很好地处理类似以下结构的内容
{
"customer": {
["field1" : "value", etc...],
["field1" : "value", etc...],
}
}
但我不知道如何让它对所提供的结构感到满意。
使用默认的 JsonConvert.DeserializeObject(content) 会产生正确的 Customer 数量,但所有数据均为空。
对 CustomerList(如下)执行某些操作会导致“无法反序列化当前 JSON 数组”异常
public class CustomerList
{
public List<Customer> customer { get; set; }
}
想法?
您可以创建一个新模型来反序列化您的 JSON
CustomerJson
:
public class CustomerJson
{
[JsonProperty("customer")]
public Customer Customer { get; set; }
}
public class Customer
{
[JsonProperty("first_name")]
public string Firstname { get; set; }
[JsonProperty("last_name")]
public string Lastname { get; set; }
...
}
您可以轻松反序列化您的 JSON:
JsonConvert.DeserializeObject<List<CustomerJson>>(json);
对于那些不想创建任何模型的人,请使用以下代码:
var result = JsonConvert.DeserializeObject<
List<Dictionary<string,
Dictionary<string, string>>>>(content);
注意:这可能不适用于您的 JSON 字符串。这不是任何 JSON 结构的通用解决方案。它适用于问题中的 JSON 结构。对于你自己的JSON结构,你需要调整代码。
使用接受的答案,您必须使用CustomerJson
类,这有点烦人。如果您不想这样做,可以使用以下方法:
public class CustomerList
{
[JsonConverter(typeof(MyListConverter))]
public List<Customer> customer { get; set; }
}
请注意,我使用的是 List<>
,而不是数组。现在创建以下类:
class MyListConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
var list = Activator.CreateInstance(objectType) as System.Collections.IList;
var itemType = objectType.GenericTypeArguments[0];
foreach (var child in token.Values())
{
var childToken = child.Children().First();
var newObject = Activator.CreateInstance(itemType);
serializer.Populate(childToken.CreateReader(), newObject);
list.Add(newObject);
}
return list;
}
public override bool CanConvert(Type objectType)
{
return objectType.IsGenericType && (objectType.GetGenericTypeDefinition() == typeof(List<>));
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}
对上述内容稍作修改。我的 Json 格式,经过验证是 {
mycollection:{[
{
property0:value,
property1:value,
},
{
property0:value,
property1:value,
}
]
}
}
使用 AlexDev 的回应,我这样做了循环每个孩子,从中创建读者
public partial class myModel
{
public static List<myModel> FromJson(string json) => JsonConvert.DeserializeObject<myModelList>(json, Converter.Settings).model;
}
public class myModelList {
[JsonConverter(typeof(myModelConverter))]
public List<myModel> model { get; set; }
}
class myModelConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
var list = Activator.CreateInstance(objectType) as System.Collections.IList;
var itemType = objectType.GenericTypeArguments[0];
foreach (var child in token.Children()) //mod here
{
var newObject = Activator.CreateInstance(itemType);
serializer.Populate(child.CreateReader(), newObject); //mod here
list.Add(newObject);
}
return list;
}
public override bool CanConvert(Type objectType)
{
return objectType.IsGenericType && (objectType.GetGenericTypeDefinition() == typeof(List<>));
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}
JC_VA 的进一步修改,取他已有的,并将 MyModelConverter 替换为...
public class MyModelConverter : JsonConverter
{
//objectType is the type as specified for List<myModel> (i.e. myModel)
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader); //json from myModelList > model
var list = Activator.CreateInstance(objectType) as System.Collections.IList; // new list to return
var itemType = objectType.GenericTypeArguments[0]; // type of the list (myModel)
if (token.Type.ToString() == "Object") //Object
{
var child = token.Children();
var newObject = Activator.CreateInstance(itemType);
serializer.Populate(token.CreateReader(), newObject);
list.Add(newObject);
}
else //Array
{
foreach (var child in token.Children())
{
var newObject = Activator.CreateInstance(itemType);
serializer.Populate(child.CreateReader(), newObject);
list.Add(newObject);
}
}
return list;
}
public override bool CanConvert(Type objectType)
{
return objectType.IsGenericType && (objectType.GetGenericTypeDefinition() == typeof(List<>));
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}
这应该适用于 json
myModelList{
model: [{ ... object ... }]
}
或
myModelList{
model: { ... object ... }
}
它们最终都会被解析,就像它们一样
myModelList{
model: [{ ... object ... }]
}
简单:创建两个类,一个用于客户,另一个用于数组对象。
{
"fieldObjects": [
{
"Field1": "ValueField1_a",
"Field2": "ValueField2_a"
},
{
"Field1": "ValueField1_b",
"Field2": "ValueField2_b"
}
]
}
最后使用父类对 Json 字符串使用 DeserializeObject,而不使用 ...就这些了
CustomerList customers = JsonSerializer.Deserialize<CustomerList>(json);
或
List<Customer> customers = JsonSerializer.Deserialize<List<Customer>>(json);
前者是您自己的 POCO 类,其属性组合可以是标量或数组。后者,用于反序列化特定的数组对象。