JSON.NET 反序列化存储为属性的 JSON 对象

Gui*_*ite 3 c# json json.net deserialization

我有一条 JSON 消息要使用包含另一个对象的 JSON 的字符串属性进行反序列化。我有以下课程

public class Envelope
{
    public string Type { get; set; }
    public Message InnerMessage { get; set; }
}

public class Message
{
    public string From { get; set; }
    public string To { get; set; }
    public string Body { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我收到的 JSON 消息采用以下格式:

{
    Type : "send",
    InnerMessage : "{ From: \"sender\", To: \"receiver\", Body: \"test\" }"
}
Run Code Online (Sandbox Code Playgroud)

请注意,它InnerMessage包含类的序列化Message,而不是类的 JSON。

InnerMessage如果我将属性的类型保留为Message,标准 JSON.NET 反序列化将失败。

如果我更改InnerMessageto string,序列化可以工作,但是在我需要再次反序列化InnerMessagetoMessage类的内容之后:

Envelope envelope = JsonConvert.DeserializeObject<Envelope>(jsonMessage);
Message innerMessage = JsonConvert.DeserializeObject<Envelope>(envelope.InnerMessage);
Run Code Online (Sandbox Code Playgroud)

有某种方法可以保留toInnerMessage的属性并告诉 JSON.NET 自动处理要反序列化的字符串值吗?EnvelopeMessage

Sir*_*ufo 5

你需要定制JsonConverter

class StringTypeConverter : Newtonsoft.Json.JsonConverter
{
    public override bool CanRead => true;
    public override bool CanWrite => true;

    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        string json = (string)reader.Value;
        var result = JsonConvert.DeserializeObject(json, objectType);
        return result;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var json = JsonConvert.SerializeObject(value);
        serializer.Serialize(writer, json);
    }
}
Run Code Online (Sandbox Code Playgroud)

并将 a 添加到属性JsonConverterAttribute中InnerMessage

public class Envelope
{
    public string Type { get; set; }
    [Newtonsoft.Json.JsonConverter(typeof(StringTypeConverter))]
    public Message InnerMessage { get; set; }
}

public class Message
{
    public string From { get; set; }
    public string To { get; set; }
    public string Body { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以Envelope使用以下命令序列化/反序列化该类

var envelope = JsonConvert.DeserializeObject<Envelope>( jsonMessage );
Run Code Online (Sandbox Code Playgroud)