如何使用 System.Text.Json 将 Arraylist 项反序列化为具体类型?

How to deserialize Arraylist items into concrete type using System.Text.Json?

我有以下测试类

public class Test
{
    public int MyProperty { get; set; }            
    public ArrayList list { get; set; }
}
public class Employee
{
    public int MyProperty { get; set; }
    public string Name { get; set; }
}

和下面的代码

static void Main(string[] args)
{
    Employee e1 = new Employee();
    e1.MyProperty = 1;
    e1.Name = "Yash";
    Employee e2 = new Employee();
    e2.MyProperty = 1;
    e2.Name = "Yash";
    Test t = new Test();
    t.list = new ArrayList();
    t.list.Add(e1);
    t.list.Add(e2);
    string text = JsonSerializer.Serialize(t);
    Test t2 = new Test();
    t2 = JsonSerializer.Deserialize<Test>(text);
}

当我使用 Newtonsoft 反序列化时,我在数组列表中看到 JObjects 而不是 Employee 对象。我能够通过创建 ArrayList 转换器使用 Newtonsoft.Json 解决这个问题。

然而,System.text.Json 却无法做到这一点。如何使用 System.Text.Json 反序列化此 ArrayList?这是我需要支持的古老代码,每次我反序列化一个 ArrayList 时,我都知道它应该包含哪种对象类型。

如果您事先知道 ArrayList 应该包含某种类型的项目,您可以轻松地创建一个 JsonConverter<ArrayList> 来序列化和反序列化 ArrayList,如下所示:

public class KnownItemTypeArrayListConverter<TItem> : JsonConverter<ArrayList>
{
    public override ArrayList Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
        new ArrayList(JsonSerializer.Deserialize<List<TItem>>(ref reader, options));
        
    public override void Write(Utf8JsonWriter writer, ArrayList value, JsonSerializerOptions options) =>
        JsonSerializer.Serialize(writer, value.Cast<TItem>(), options);
}

然后您可以使用它来序列化和反序列化您的 Test 模型,如下所示:

var e1 = new Employee { MyProperty = 1, Name = "Yash", };
var e2 = new Employee { MyProperty = 1, Name = "Yash", };
var t = new Test { list = new ArrayList { e1, e2 }, };

var options = new JsonSerializerOptions
{
    Converters = { new KnownItemTypeArrayListConverter<Employee>() },
};

var text = JsonSerializer.Serialize(t, options);

var t2 = JsonSerializer.Deserialize<Test>(text, options);

演示 fiddle #1 here.

或者,您可以使用 JsonConverterAttribute:

将转换器应用于您的模型
public class Test
{
    public int MyProperty { get; set; }  
    [System.Text.Json.Serialization.JsonConverter(typeof(KnownItemTypeArrayListConverter<Employee>))]
    public ArrayList list { get; set; }
}

(我使用完全限定的类型名称以避免与 Newtonsoft 的 JsonConverterAttribute 混淆。)

演示 fiddle #2 here.

也就是说,ArrayList 的使用已被弃用。来自 docs:

We don't recommend that you use the ArrayList class for new development. Instead, we recommend that you use the generic List<T> class.

您可以考虑升级旧代码以使用以下模型:

public class Test
{
    public int MyProperty { get; set; }            
    public List<Employee> list { get; set; }
}