JSON.NET:将json字符串属性序列化为json对象

21

有没有办法告诉 JSON.NET 我有一个包含 JSON 数据的字符串?例如,我有一个这样的类:

public class Foo
{
    public int Id;
    public string RawData;
}

我使用它的方式如下:

var foo = new Foo();
foo.Id = 5;
foo.RawData = @"{""bar"":42}";
我希望你能将其序列化为这样:
{"Id":5,"RawData":{"bar":42}}

基本上,我有一段已经存储为JSON格式的非结构化可变长度数据,我需要完全序列化的对象来将此数据作为部分包含。

谢谢。

编辑:为确保正确理解,这是单向序列化,即我不需要将其反序列化为同一对象;其他系统将处理此输出。我需要RawData的内容成为JSON的一部分,而不仅仅是字符串。


是的,这是可能的,但您能告诉我您需要什么样的输出吗?目前输出为:{"Id":5,"RawData":"{"bar":42}"}。 - user2535425
@Rivers,这正是我所需要的。我有一个字符串属性,其中包含JSON内容,我认为将其反序列化仅为将其重新序列化回JSON是无用的。 - port443
@Rivers,抱歉,我没有好好阅读您的示例。在您的情况下,JSON中的RawData内容是字符串,而我需要它成为一个子对象(即您的变量添加了额外的引号和反斜杠)。 - port443
3个回答

23
你需要一个转换器来完成这个任务,下面是一个示例:
public class RawJsonConverter : JsonConverter
{
   public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
   {
       writer.WriteRawValue(value.ToString());
   }

   public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
   {
        using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture)) 
        {
            using (var jsonTextWriter = new JsonTextWriter(stringWriter))
            {
                jsonTextWriter.WriteToken(reader);
                var result = stringWriter.ToString();
                return result;
            }
        }
   }

   public override bool CanConvert(Type objectType)
   {
       return typeof(string).IsAssignableFrom(objectType);
   }
   
   public override bool CanRead
   {
       get { return true; }
   }   
}

然后在你的类上使用它进行装饰:

public class Foo
{
    public int Id;
    [JsonConverter(typeof(RawJsonConverter))]
    public string RawData;
}

然后,当你使用:

var json = JsonConvert.SerializeObject(foo,
                                    new JsonSerializerSettings());
Console.WriteLine (json);

这是您的输出:

{"Id":5,"RawData":{"bar":42}}

希望能有所帮助。
编辑:我已经更新了我的答案,提供了更高效的解决方案,之前的方法强制你进行序列化再反序列化,而这个方法则不需要。
编辑,2023年5月11日:将JsonConverter改为支持反序列化。

我得自己试试,但看起来它解决了我的问题。谢谢@ Rivers. - port443

7

有可能使用 JRaw 可以更适合且更紧凑的解决方案。

请参阅此帖子


4
您可以使用另一个属性来反序列化对象属性的JSON。
public class Foo
{
    public int Id;
    public string RawData;
    private object thisObject;
    public object ThisObject 
    {
        get
        {
            return thisObject ?? (thisObject = JsonConvert.DeserializeObject<object>(RawData));
        }
    }        
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接