如何使用 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; }
}
我有以下测试类
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 genericList<T>
class.
您可以考虑升级旧代码以使用以下模型:
public class Test
{
public int MyProperty { get; set; }
public List<Employee> list { get; set; }
}