我有一个看起来像这样的JSON提要(我删除了一些本示例不需要的字段):
{
"total_count": 2,
"num_pages": 1,
"current_page": 1,
"balance": {
"amount": "0.00001199",
"currency": "BTC"
},
"transactions": [
{
"transaction": {
"id": "5018f833f8182b129c00002f",
"created_at": "2012-08-01T02:34:43-07:00",
"sender": {
"id": "5011f33df8182b142400000e",
"name": "User Two",
"email": "[email protected]"
},
"recipient": {
"id": "5011f33df8182b142400000a",
"name": "User One",
"email": "[email protected]"
}
}
},
{
"transaction": {
"id": "5018f833f8182b129c00002e",
"created_at": "2012-08-01T02:36:43-07:00",
"hsh": "9d6a7d1112c3db9de5315b421a5153d71413f5f752aff75bf504b77df4e646a3",
"sender": {
"id": "5011f33df8182b142400000e",
"name": "User Two",
"email": "[email protected]"
},
"recipient_address": "37muSN5ZrukVTvyVh3mT5Zc5ew9L9CBare"
}
}
]
}
有两种类型的交易在这个饲料:有一个内部事务recipient
有一个和外部交易hsh
和recipient_address
。
我创建了以下类来适应这种结构:
因此,我们为所有分页结果(PagedResult
)提供了基类,并为交易(TransactionPagedResult
)提供了特定的实现。此结果具有一个包含0 .. *事务的集合(抽象类Transaction
)。它们不是类型Transaction
,而是类型InternalTransaction
或ExternalTransaction
的实现Transaction
。
我的问题是如何让JSON.NET处理此问题。我希望JSON.NET查看正在解析的当前事务是InternalTransaction
还是an ExternalTransaction
,然后将相应类型添加到中的IEnumerable<Transaction>
集合中TransactionPagedResult
。
我创建了自己的JsonConverter,并将其作为属性添加到IEnumerable<Transaction>
具有[JsonConverter(typeof(TransactionCreationConverter))]
属性的,但这没有用,出现以下错误:
附加信息:从JsonReader读取JObject时出错。当前JsonReader项不是对象:StartArray。路径“交易”,第1行,位置218。
我了解这是因为JSON.NET尝试对整个集合进行反序列化,但是我希望它对集合中的每个对象进行逐一反序列化。
任何人?
您的问题本质上是此问题的重复,解决方案是相同的。您需要一个JsonConverter
实例化正确的对象。但是,我看到了一些区别。
如果您从另一个答案中查看转换器的实现,则可以看到它在JSON中寻找布尔标志来确定要实例化的类型。在您的情况下,没有这样的标志,因此您需要使用字段的存在或不存在来进行此确定。另外,您在JSON中的事务列表实际上是包含事务的对象列表,因此转换器也需要考虑这一点。
进行了这些更改后,您的转换器应如下所示:
public class TransactionConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Transaction).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader,
Type objectType, object existingValue, JsonSerializer serializer)
{
JToken transaction = JToken.Load(reader)["transaction"];
if (transaction["recipient"] != null)
{
return transaction.ToObject<InternalTransaction>();
}
else
{
return transaction.ToObject<ExternalTransaction>();
}
}
public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
假设您的类是这样定义的:
class TransactionPagedResult
{
[JsonProperty(ItemConverterType=typeof(TransactionConverter))]
public IEnumerable<Transaction> Transactions { get; set; }
}
class Transaction
{
public string Id { get; set; }
[JsonProperty("created_at")]
public DateTime CreatedAt { get; set; }
}
class InternalTransaction : Transaction
{
public User Recipient { get; set; }
}
class ExternalTransaction : Transaction
{
public string Hsh { get; set; }
[JsonProperty("recipient_address")]
public string RecipientAddress { get; set; }
}
class User
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
另外,要回答问题的最后一部分,如果用[JsonConverter]
属性装饰列表,则转换器应处理整个列表。要处理单个项目,您需要改为使用[JsonProperty(ItemConverterType=typeof(TransactionConverter))]
列表。我已经编辑了上面的类定义以使其更加清楚。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句