Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# JSON.NET反序列化存储为属性的JSON对象_C#_Json_Json.net_Deserialization - Fatal编程技术网

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

C# JSON.NET反序列化存储为属性的JSON对象,c#,json,json.net,deserialization,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; }

我有一条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; }
}
我收到的JSON消息的格式如下:

{
    Type : "send",
    InnerMessage : "{ From: \"sender\", To: \"receiver\", Body: \"test\" }"
}
请注意,
InnerMessage
包含
Message
类的序列化,而不是类的JSON

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

如果我将
InnerMessage
更改为
string
,序列化工作正常,但在我需要将
InnerMessage
的内容再次反序列化为
Message
类之后:

Envelope envelope = JsonConvert.DeserializeObject<Envelope>(jsonMessage);
Message innerMessage = JsonConvert.DeserializeObject<Envelope>(envelope.InnerMessage);
Envelope信封=JsonConvert.DeserializeObject(jsonMessage);
Message innerMessage=JsonConvert.DeserializeObject(envelope.innerMessage);

有一种方法可以将
信封的
InnerMessage
属性保留到
Message
,并告诉JSON.NET处理要自动反序列化的字符串值?

您可以使用自定义转换器来实现这一点。例如:

public class EnvelopeConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, 
        JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, 
        object existingValue, JsonSerializer serializer)
    {
        var envelope = JObject.Load(reader);

        var type = envelope["Type"].ToString();
        var message = JsonConvert.DeserializeObject<Message>(
            envelope["InnerMessage"].ToString());

        return new Envelope
        {
            Type = type,
            InnerMessage = message
        };
    }

    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }
}
公共类信封转换器:JsonConverter
{
公共重写void WriteJson(JsonWriter writer,对象值,
JsonSerializer(序列化程序)
{
抛出新的NotImplementedException();
}
公共重写对象ReadJson(JsonReader reader,类型objectType,
对象存在值,JsonSerializer序列化程序)
{
var信封=JObject.Load(读卡器);
变量类型=信封[“类型”]。ToString();
var message=JsonConvert.DeserializeObject(
信封[“InnerMessage”].ToString());
退回新信封
{
类型=类型,
InnerMessage=消息
};
}
公共覆盖布尔可读取
{
获取{return true;}
}
公共覆盖布尔CanConvert(类型objectType)
{
返回true;
}
}
然后像这样使用它:

Envelope envelope = JsonConvert.DeserializeObject<Envelope>(
    jsonMessage, new EnvelopeConverter());
Envelope信封=JsonConvert.DeserializeObject(
jsonMessage,new-EnvelopeConverter());

您需要一个定制的
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);
    }
}
并在
InnerMessage
属性中添加一个
JsonConverterAttribute

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; }
}
现在,您可以使用

var envelope = JsonConvert.DeserializeObject<Envelope>( jsonMessage );
var envelope=JsonConvert.DeserializeObject(jsonMessage);

如何序列化对象?当我使用
JsonConvert.SerializeObject(envelope)
时,我得到的Json输出与您不同。我从Web服务中获得Json,我只需要将其反序列化到我创建的类中,看起来@SirRufo有您寻找的答案,您的解决方案看起来比另一个更干净,明天我将测试它,以获得您的答案,但就我个人而言,我更喜欢鲁福爵士的作品,因为我可以适用于特定的财产,而不是阶级