如何知道在反序列化JSON字符串时将jobobject强制转换为什么类型



我知道过去使用Newtonsoft反序列化有很多问题,但我还没有找到完全符合我情况的东西。(如果我无意中问了一个重复的问题,请告诉我,我很难相信我是第一个遇到这种情况的人。)

我有一个像这样的对象结构:

public class Logger
    {
        public List<MethodAPI> List { get; set; }
    }
    private class MethodAPI
    {
        public string MethodName { get; set; }
        public List<Parameter> Parameters { get; set; }
    }

现在对于类型,我在反序列化方面遇到了麻烦。如果我这样做:

    public class Parameter
    {
        public IProduct data { get; set; }
    }

那么反序列化工作得很好。然而,直到运行时我才真正知道data是什么类型。但是,如果我执行以下操作:

public class Parameter
{
   public object data { get; set; }
}

很明显,当我反序列化它的时候Newtonsoft没有办法解决它应该是什么类型。因此,它只是使它成为JObject

通常,我只编写一个自定义转换器。但是,我不确定在这种情况下如何实现ReadJson方法。

public class ParameterConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType.Equals(typeof(Parameter));
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            // I'd rather just do serializer.Deserialize<Parameter>(reader) here but that'll cause a stack overflow exception
            object obj = serializer.Deserialize(reader);
            Parameter param = (obj as JObject).ToObject<Parameter>();
            // This works great if I know that I'm converting this to IProduct, but is there an elegant way to figure out what type to use here?
            // I have to pass the serializer here because the serializer can "map" IProduct and several of its "child" types to its implementation
            param.data = (param.data as JObject).ToObject(typeof(IProduct), serializer);
            return param;
        }
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // Serialization's no problem
            serializer.Serialize(writer, value);
        }
    }

正如我在代码注释中提到的,我感到困惑的部分是如何根据原始JSON确定原始对象的类型。有没有人有什么不难看的办法?

感谢@ l.b.。关于这一点——我有点不好意思错过了这一点,但我所需要做的就是

new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Objects }

不需要自定义转换器。

c#中一个美丽的新事物是新声明的类型dynamic。这在本质上与在JavaScript中声明var是一样的(如果你熟悉的话)。

你的类是:

public class Parameter
{
   public dynamic data { get; set; }
}

现在我可以在代码中创建它的一个实例并随意使用它:

Parameter param = new Parameter();
string foo = JsonConvert.SerializeObject(some_object);
// If you know the object type (in this case the object type is IProduct)
param.data = JsonConvert.DeserializeObject<IProduct>(foo);
// If you don't know the object type
param.data = JsonConvert.DeserializeObject<ExpandoObject>(foo, new ExpandoObjectConverter());

expando对象是一个c#类,它允许你创建动态对象,允许你调用任何方法,并在运行时对其求值。

例如

dynamic foo = new ExpandoObject();
// Creates a member variable named bar
foo.bar = "Hello, World!";
// Throws an runtime error because bar2 is undefined
Console.WriteLine(foo.bar2);

我不知道这是否是你的问题,但知道它是有帮助的:)

最新更新