簡體   English   中英

將 JSON 反序列化為具有泛型類型參數的接口列表

[英]Deserialization of JSON to List of Interface with generic type parameter

正如標題所提到的,我正在嘗試反序列化 JSON,但遇到了一些麻煩。 我認為下面包括必要的信息。

public class Variable<T> : IVariable where T : IConvertible
{
    //...
}

public class ArrayVariable<T> : IVariable where T : IConvertible
{
    //...
}

所以我有一個 Ivariable 列表,然后我成功地序列化了它(所有信息都在 json 中):

JsonConvert.SerializeObject(myIVariableList)

現在我正在嘗試反序列化它,但我無法確定正確的方法來執行它,因為除了類型VariableArrayVariable之外,它還涉及找到泛型類型T 我已經試過了

JsonConvert.DeserializeObject<List<IVariable>>(result.newValues)

但顯然,您可以創建接口的實例。 任何幫助將非常感激。

您可以使用TypeNameHandling.All將類型信息添加到序列化的 json 中,然后在解析過程中使用它:

var variables = new List<IVariable>()
{
    new Variable<int>()
};
var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
var serializeObject = JsonConvert.SerializeObject(variables, settings);
var list = JsonConvert.DeserializeObject<List<IVariable>>(serializeObject, settings);

您可以使用TypeNameHandling.All但我強烈建議您避免使用它,因為它非常危險並且允許攻擊者破壞您的代碼

另一個更安全的選擇是使用自定義轉換器。 這是一個非常簡單(且脆弱)的示例,可以幫助您入門:

首先讓我們創建一些共享接口的基本類:

public interface IVariable { }

public class Foo : IVariable
{
    public int A { get; set; }
}

public class Bar : IVariable
{
    public int B { get; set; }
}

現在我們可以制作我們的轉換器:

public class IVariableConverter : JsonConverter<IVariable>
{
    public override IVariable ReadJson(JsonReader reader, Type objectType, 
        IVariable existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // First load the JSON into a JObject
        var variable = JObject.Load(reader);

        // If the JSON had a property called A, it must be a Foo:
        if (variable.ContainsKey("A"))
        {
            return variable.ToObject<Foo>();
        }

        // If the JSON had a property called B, it must be a Bar:
        if (variable.ContainsKey("B"))
        {
            return variable.ToObject<Bar>();
        }

        // And who knows what was passed in if it was missing both of those properties?!
        throw new Exception("Er, no idea what that JSON was supposed to be!");


    }

    public override void WriteJson(JsonWriter writer, IVariable value, 
        JsonSerializer serializer)
    {
        // Feel free to write your own code here if you need it
        throw new NotImplementedException();
    }
}

現在我們可以做一些實際的反序列化:

// A basic JSON example:
var json = "[{\"A\":1},{\"B\":2}]";

// The settings to tell the serialiser how to process an IVariable object
var settings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new IVariableConverter() }
};

// And deserialise with the defined settings
var result = JsonConvert.DeserializeObject<List<IVariable>>(json, settings);

您將需要在如何識別每種類型方面更具創造性,但這是實現您需要的安全方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM