使用Json.NET自定义反序列化

Hab*_*lah 13 .net c# serialization json json.net

我上课了

public class Order
{
   public int Id { get; set; }
   public string ShippingMethod { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我想将下面的JSON数据反序列化为上面的类/对象

string json = @"{
  'Id': 1,
  'ShippingMethod': {
     'Code': 'external_DHLExpressWorldwide',
     'Description': 'DHL ILS Express Worldwide'
  }
}";
Run Code Online (Sandbox Code Playgroud)

我的想法是,ShippingMethod在JSON是一个对象,但我只想去ShippingMethod.Code(以JSON),将传递到ShippingMethodstringOrder反序列化过程中的类.

如何使用Json.NET实现这一目标?

我相信我可以使用CustomJsonConverter来完成它.但我感到困惑.文档中的示例仅适用于WriteJson但不是ReadJson.

Hab*_*lah 27

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;
    }
}
Run Code Online (Sandbox Code Playgroud)


L.B*_*L.B 8

您可以使用JsonPropertyJsonIgnore属性来指导反序列化过程......所以您的模型可以是:

public class Order
{
    public int Id { get; set; }

    [JsonIgnore]
    public string ShippingMethod
    {
        get
        {
            return (string)TempShippingMethod?["Code"];
        }
    }

    [JsonProperty("ShippingMethod")]
    private JObject TempShippingMethod { set; get; }
}
Run Code Online (Sandbox Code Playgroud)
var res = JsonConvert.DeserializeObject<Order>(json);
Run Code Online (Sandbox Code Playgroud)

  • 我不同意这是一个黑客。JsonIgnore 就是为这种目的而设计的——这意味着您不必重新编写序列化。据推测,我们缺少一些关于为什么这不适合 OP 的上下文。 (5认同)

Tin*_*wor 8

 dynamic o = JsonConvert.DeserializeObject(json);
 var order = new Order
 {
     Id = o.Id,
     ShippingMethod = o.ShippingMethod.Code
 };
Run Code Online (Sandbox Code Playgroud)

将对象反序列化为动态,然后Order通过访问动态对象属性来填充对象