如何使用JSON.NET在运行时更改反序列化类型?

时间:2013-12-03 14:16:58

标签: c# .net json json.net

我正在尝试将一些属性添加到从外部程序集到达的模型中(无法修改)。因此,我获取模型,将其序列化为JSON,然后反序列化为动态对象(ExpandoObject),添加新属性,将动态对象序列化为JSON;但是当我尝试反序列化时,因为每个人都应该期望包含的类型是用原始类型(示例中的A类)反序列化而不是扩展(示例中的ExtendedA)。请参阅以下代码:

public static class Extensions
{
    private static object ConvertJTokenToObject(JToken token)
    {
        if (token is JValue)
        {
            return ((JValue)token).Value;
        }
        if (token is JObject)
        {
            var expando = new ExpandoObject();
            (from childToken in ((JToken)token) where childToken is JProperty select childToken as JProperty).ToList().ForEach(property =>
            {
                ((IDictionary<string, object>)expando).Add(property.Name, ConvertJTokenToObject(property.Value));
            });
            return expando;
        }
        if (token is JArray)
        {
            object[] array = new object[((JArray)token).Count];
            int index = 0;
            foreach (JToken arrayItem in ((JArray)token))
            {
                array[index] = ConvertJTokenToObject(arrayItem);
                index++;
            }
            return array;
        }
        throw new ArgumentException(string.Format("Unknown token type '{0}'", token.GetType()), "token");
    }

    public static ExpandoObject ToExpando(this string json)
    {
        JObject jsonObject = JObject.Parse(json);
        dynamic dynObject = ConvertJTokenToObject(jsonObject);
        return (ExpandoObject)dynObject;
    }
}

public class A //Defined in an external assembly
{
    public string Property1 { get; set; }
}

public class B //Defined in an external assembly
{
    public List<A> Properties { get; set; }
}

public class ExtendedA : A
{
    public string Property2 { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var myObject = new B() //This is an example but in real code this object arrive from an external module that can't be modified, something like: B myObject = ExternalAssembly.GetB();
        {
            Properties = new List<A>()
            {
                new A() { Property1 = "value 1" },
                new A() { Property1 = "value 2" },
                new A() { Property1 = "value 3" }
            }
        };
        string jsonObject = JsonConvert.SerializeObject(myObject);
        dynamic expandoObject = jsonObject.ToExpando();
        for (int index = 0; index < expandoObject.Properties.Length; index++)
        {
            expandoObject.Properties[index].Property2 = Guid.NewGuid();
        }
        jsonObject = JsonConvert.SerializeObject(expandoObject);
        B myExtendedObject = JsonConvert.DeserializeObject<B>(jsonObject);
    }
}

如何以一种使用类ExtendedA而不是类A的方式反序列化“新创建的类型”?有一种方法可以在反序列化调用中指定映射器吗?有什么建议吗?

0 个答案:

没有答案