如何使用json.net自定义反序列化为对象
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用json.net自定义反序列化为对象相关的知识,希望对你有一定的参考价值。
我使用http://json2csharp.com/生成一个代表我的JSON的csharp类,它运行得非常好。但是,在与第三方api合作一段时间之后,我意识到他们的响应并不总是发送相同类型的数据。我正在查询他们的票证数据API,每张票都有一个SellPrice。有时他们将SellPrice作为Money对象返回,该对象具有货币(字符串)和金额(double),有时他们将其作为双精度发回。所以我试图找到一种方法来优雅地处理这个问题,这样我总是设置我的SellPrice对象的数量。这是在将Money对象作为SellPrice发送时有效的代码的简短版本
public class Ticket
{
public string Ticket_Id {get; set;}
//... other fields
public SellPrice SellPrice {get; set;}
}
public class SellPrice
{
public string Currency {get; set;}
public double Amount {get; set;}
}
然后当我得到Json时,我会这样反序列化,这很有效......
for (int i = 0; i < jItems.Count; i++)
{
TUTicket2 item = jItems[i].ToObject<TUTicket2>();
}
...直到我遇到一个返回double而不是对象的API调用。
所以只看它是Money对象的情况,我想我会尝试创建一个构造函数,以便我可以根据对象类型设置值,如下所示:
public class SellPrice
{
public SellPrice(object sellPrice)
{
if (sellPrice.GetType() == typeof(Dictionary<string, object>))
{
Currency = (string)((Dictionary<string, object>)sellPrice)["Currency"];
Amount = (double)((Dictionary<string, object>)sellPrice)["Currency"];
}
}
public string Currency { get; set; }
public double Amount { get; set; }
}
但这不起作用,因为sellPrice对象总是为null,所以我想我在那里咆哮错误的树。有没有办法轻松做到这一点?我认为我的问题是它自动反序列化为对象类型的方式,但我一直在查看代码/文档,并没有弄清楚我错过了什么。
我在这里有几个目标:我们正在做足够的API工作,我希望能够利用像json2csharp这样的工具来生成类。我还想避免对每个类/对象进行手动反序列化,尽管如果这是我唯一的选择,我可以朝着那个方向前进,当99%的值表现正常时,感觉就像是矫枉过正。我也不想最终得到每个类的X个不同版本,具体取决于我所做的API调用。我试图找到一些解决方案,只让我覆盖一小部分而不是一切。对于任何反馈,我们都表示感谢。
您可以通过为您的JsonConverter
类制作自定义SellPrice
来处理此问题,如下所示:
public class SellPriceConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(SellPrice);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
SellPrice sellPrice = new SellPrice();
if (token.Type == JTokenType.Object)
{
serializer.Populate(token.CreateReader(), sellPrice);
}
else if (token.Type == JTokenType.Float)
{
sellPrice.Amount = (double)token;
// if there is a default currency, set it here, e.g.:
// sellPrice.Currency = "USD";
}
else
{
throw new JsonException("Unexpected token type for SellPrice: " + token.Type.ToString());
}
return sellPrice;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
要使用它,您需要做的就是将[JsonConverter]
属性添加到SellPrice
类,如下所示:
[JsonConverter(typeof(SellPriceConverter))]
public class SellPrice
{
...
}
然后你可以正常反序列化,它应该处理这两种情况。
这里的工作演示:https://dotnetfiddle.net/qZekyp
以上是关于如何使用json.net自定义反序列化为对象的主要内容,如果未能解决你的问题,请参考以下文章
csharp 使用Newtonsoft JSON.NET将任何对象序列化/反序列化为JSON