将JSON对象属性反序列化为字符串。

15

我有一些 JSON 数据,其中大多数属性都是简单数据类型。然而,在 JSON 中有一个属性,当我将其反序列化为 C# 类时,我只需要将其反序列化为字符串。

JSON 示例:

{"simpleProperty": "value1", "json":{"a":"a1", "b":"b1"}}

"json"对象没有固定的结构,除了它将是一个有效的JSON对象。

所以在上面的例子中,“json”的值是一个JSON对象--但是当它被反序列化时,我需要它作为一个字符串。

如果我的C#类是:

public class MyClass
{
    public string SimpleProperty { get; set; }
    public string Json { get; set; }
}

然后如果我使用:

var myClass = JsonConvert.DeserializeObject<MyClass>(jsonStr);

我希望myClass.Json只是一个简单的字符串。

我尝试创建一个自定义的JsonConverter,但这对于这么简单的事情来说似乎太复杂了。我一定错过了什么。任何指导都将不胜感激。

我也看到了这篇文章--但它并没有真正回答问题:JSON.Net - 如何将JSON反序列化为对象,但将属性视为字符串而不是JSON?

2个回答

13

你可以选择使用JToken类型的属性,以表明任何有效的JSON都可以放在那里。尽管它不完全符合您的要求,但可能已经足够了。

public class MyClass
{
    public string SimpleProperty { get; set; }
    public JToken Json { get; set; }
}

执行 myClass.Json.ToString() 将会把 JSON 以 string 的形式返回。


谢谢,但不幸的是,这对我的用例不起作用,因为该类需要在现有框架的上下文中使用,并对其进行操作。 - csheets

13

为了满足我的需求,我决定按照以下方式实现自定义的JsonConverter:

    class JsonConverterObjectToString : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return (objectType == typeof(JTokenType));
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JToken token = JToken.Load(reader);
            if (token.Type == JTokenType.Object)
            {
                return token.ToString();
            }
            return null;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            //serializer.Serialize(writer, value);

            //serialize as actual JSON and not string data
            var token = JToken.Parse(value.ToString());
            writer.WriteToken(token.CreateReader());

        }
    }

我并没有彻底测试上面的实现,而且对于Canconvert方法也不是完全确定,因为它似乎从未被调用过,但它似乎可以完成转换,然后允许我将反序列化的类存储到MongoDB中,JSON数据以字符串形式存储。所以目前一切都很好。我在实现中找到了以下有用的内容:如何使用Json.NET反序列化可以是两种不同数据类型的JSON属性

更新:修改WriteJson方法,以JSON对象的形式重新序列化(而不是字符串)。


1
如果您在类或属性上使用了[JsonConverter]属性,则不会调用CanConvert方法,因为Json.Net已经知道您的转换器可以处理该类型(通过添加属性告诉它)。如果您没有使用[JsonConverter]属性,而是通过设置将转换器实例传递给序列化程序,则会调用CanConvert。在这种情况下,Json.Net必须询问转换器是否可以处理它遇到的每种类型。因此,您希望CanConvert方法返回您的转换器设计处理的对象类型的true值。 - Brian Rogers
太好了。这救了我的一天。如果json是数组的一部分,你可以增强ReadJson() 方法,例如 else if (token.Type == JTokenType.Array) { List<object> objList = token.ToObject<List<object>>(); return objList.Select(item => item.ToString()).ToList(); } - TomB

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