使用.NET中的JavaScriptSerializer将内部结构反序列化为字符串

时间:2015-09-04 09:08:52

标签: c# .net json javascriptserializer

我正在使用.NET中的JavaScriptSerializer反序列化结构,这些结构可能是您的标准扁平键/值对,如下所示:

{
    "Value": 3.14,
    "Type": "Real"
}

或者更复杂,具有如下内部分层值对象:

{
    "Value": { "something": "test" },
    "Type": "JsonData"
}

我遇到的问题是,在"Type": "JsonData"的情况下,对象可以是任意的。我不能假设它的结构是什么。

然而,"上层&#34>我的应用程序将知道如何处理这些数据。

因此,我需要找出一种方法来将 Value 字段保留为字符串,无论它是否包含整数,字符串或完整的JSON结构。基本上,我不希望JavaScriptSerializer解析其中的任何内容。我希望能够有这样一堂课:

public class JsonObject
{
    public string Value { get; set; }
    public string Type { get; set; }
}

Value包含我的JSON中未处理的vanilla值。

有没有办法告诉.NET不要解析我的JSON的某些部分?

不建议使用其他库,如JSON.NET 。我知道它可能会做到这一点,但这是一个项目将作为一个库分发 - 这就是为什么我宁愿我的库只依赖于标准的.NET框架。

2 个答案:

答案 0 :(得分:1)

没有一个属性可以指示JavaScriptSerializer不要解析特定的JSON属性(除了完全忽略它,这不是你想要的)。但是,你可以创建一个JavaScriptConverter来有效地重新序列化有问题的属性,这样你仍然可以得到你想要的结果:所有值最终都是字符串。

以下是转换器的外观:

public class JsonObjectConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get { return new List<Type> { typeof(JsonObject) }; }
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        JsonObject obj = new JsonObject();
        obj.Type = (string)dictionary["Type"];
        obj.Value = serializer.Serialize(dictionary["Value"]);
        return obj;
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

要使用转换器,您必须使用JavaScriptSerializer方法将其注册到RegisterConverters。这是一个演示:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        [
            {
                ""Value"" : ""foo bar"",
                ""Type"" : ""String""
            },
            {
                ""Value"" : 3.14,
                ""Type"" : ""Real""
            },
            {
                ""Value"" : 
                {
                    ""Something"" : ""Test"",
                    ""Items"" : [""A"", ""B"", ""C""]
                },
                ""Type"" : ""JsonData""
            },
            {
                ""Value"" : 42,
                ""Type"" : ""Integer""
            }
        ]";

        JavaScriptSerializer jss = new JavaScriptSerializer();
        jss.RegisterConverters(new List<JavaScriptConverter> { new JsonObjectConverter() });

        List<JsonObject> list = jss.Deserialize<List<JsonObject>>(json);
        foreach (JsonObject item in list)
        {
            Console.WriteLine(string.Format("({0}) {1}", item.Type, item.Value));
        }
    }
}

public class JsonObject
{
    public string Value { get; set; }
    public string Type { get; set; }
}

输出:

(String) "foo bar"
(Real) 3.14
(JsonData) {"Something":"Test","Items":["A","B","C"]}
(Integer) 42

答案 1 :(得分:0)

试试这个:

public class JsonObject
{
    public object Value { get; set; }
    public object Type { get; set; }
}