使用 Json.NET 自定义反序列化
Posted
技术标签:
【中文标题】使用 Json.NET 自定义反序列化【英文标题】:Custom Deserialization using Json.NET 【发布时间】:2017-03-19 06:26:27 【问题描述】:我有课
public class Order
public int Id get; set;
public string ShippingMethod get; set;
我想将下面的 JSON 数据反序列化到上面的类/对象中
string json = @"
'Id': 1,
'ShippingMethod':
'Code': 'external_DHLExpressWorldwide',
'Description': 'DHL ILS Express Worldwide'
";
我的想法是 JSON 中的 ShippingMethod
是一个对象,但我只想到达 ShippingMethod.Code
(在 JSON 中),它将在反序列化期间作为 string
在 Order
类中传递给 ShippingMethod
。
我怎样才能使用Json.NET 实现这个目标?
我相信我可以使用CustomJsonConverter 来完成它。但我很困惑。文档中的示例仅适用于 WriteJson
,但不适用于 ReadJson
。
【问题讨论】:
所以Code
和Description
在ShippingMethod
里面?如何序列化?
你只需要“Id”和“Code”在同一级别?
是的,这是我的问题,也是我想要完成的目标
ShippingMethod
是 json 中的对象和 C# 类中的字符串。你怎么能映射这个。您必须按如下方式更改代码。
@Aruna 查看我的映射方式***.com/questions/40439290/…
【参考方案1】:
我只是使用JsonConverter
解决我的问题,正如我在上面的问题中提到的那样。下面是我的完整代码:
public class Order
public int Id get; set;
[JsonConverter(typeof(ShippingMethodConverter))]
public string ShippingMethod get; set;
public class ShippingMethodConverter : JsonConverter
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
throw new NotImplementedException("Not implemented yet");
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
if (reader.TokenType == JsonToken.Null)
return string.Empty;
else if (reader.TokenType == JsonToken.String)
return serializer.Deserialize(reader, objectType);
else
JObject obj = JObject.Load(reader);
if (obj["Code"] != null)
return obj["Code"].ToString();
else
return serializer.Deserialize(reader, objectType);
public override bool CanWrite
get return false;
public override bool CanConvert(Type objectType)
return false;
【讨论】:
【参考方案2】: dynamic o = JsonConvert.DeserializeObject(json);
var order = new Order
Id = o.Id,
ShippingMethod = o.ShippingMethod.Code
;
将对象反序列化为动态对象,然后通过访问动态对象属性来填充Order
对象
【讨论】:
这个+1。我认为这是没有属性污染和新类创建的最佳清洁方式:) 谢谢你的回答,但是如果有很多其他属性就不适合了 你还没有说还有更多的属性需要管理。为了解决这个问题,你可以添加一个映射一次的扩展方法,然后你可以在任何你想要的地方使用它。但是你的解决方案似乎还可以,只是两个属性的代码行(在我看来) 是的,看起来有很多代码,但实际上它会让你的模型保持干净。【参考方案3】:您可以使用JsonProperty
和JsonIgnore
属性来指导反序列化过程...所以您的模型可以是:
public class Order
public int Id get; set;
[JsonIgnore]
public string ShippingMethod
get
return (string)TempShippingMethod?["Code"];
[JsonProperty("ShippingMethod")]
private JObject TempShippingMethod set; get;
var res = JsonConvert.DeserializeObject<Order>(json);
【讨论】:
是的,这只是一个小技巧。我不喜欢这种方式,但我赞成 :) 尊重你的回答 @Habibillah 我也不喜欢你的回答,对于一个简单的事情来说太麻烦了,但我尊重你的意见,我发布了我的回答的简化版本.. 不用担心 :)。问题很简单,但我的真实想法是,有很多属性和糟糕的 json 架构,它真的很值得。例子。保存订单,您必须传递字符串,但要获取订单详细信息,您需要一个对象。还有更多 我不同意这是一个 hack。 JsonIgnore 就是为这种目的而设计的——这意味着您不必重新编写序列化。据推测,我们缺少一些关于为什么这不适合 OP 的上下文。以上是关于使用 Json.NET 自定义反序列化的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Json.Net 序列化/反序列化具有附加属性的自定义集合
如何使用 Json.Net 序列化/反序列化带有自定义键的字典?
JSON.Net无法在自定义JsonConverter中反序列化json数组