简体   繁体   English

如何序列化继承的 ICollection 中的属性<t> class?</t>

[英]How can I serialize a property in an inherited ICollection<T> class?

I have a class that presented like我有一个 class 像

public class ItemCollection<T> : ICollection<T> {
    public ItemCollection() {
        Items = new List<T>();
    }
    public List<T> Items { get; set; }
    ...
}

Now it will be serialized into:现在它将被序列化为:

{
    "Property": [{...}]
}

But I want the result is like:但我想要的结果是这样的:

{
    "Property": {"Items": [{...}]}
}

Sorry for the missing information of this question.抱歉,这个问题缺少信息。

I now stuck in serialization when using System.Text.Json.我现在在使用 System.Text.Json 时陷入序列化。

In Newtonsoft.Json, I use [JsonObject] to annotate this class so it can serialization correctly into json with "Items": value , but I don't know how to serialize the Items property using System.Text.Json. In Newtonsoft.Json, I use [JsonObject] to annotate this class so it can serialization correctly into json with "Items": value , but I don't know how to serialize the Items property using System.Text.Json.

I have some classes inherited this class and the inheritances will be as properties in other classes.我有一些类继承了这个 class 并且继承将作为其他类中的属性。

Solution:解决方案:

Thank you for every one that answered this question, I have found a solution to solve this.感谢每个回答这个问题的人,我已经找到了解决这个问题的方法。 I create a ConverterFactory to resolve the needed types to create the converters.我创建了一个ConverterFactory来解析创建转换器所需的类型。 In the converter, I create new JsonObject and use Reflection to create the properties in the type, after this, I serialize the JsonObject so I can get the correct result.在转换器中,我创建了新的JsonObject并使用Reflection来创建类型中的属性,之后,我序列化了JsonObject以便获得正确的结果。

Thank you for your question, but I did not found any difference between the serialization of Newtonsoft and System.Text.Json.谢谢你的提问,但是我没有发现 Newtonsoft 和 System.Text.Json 的序列化有什么区别。

Perhabs you can provide an example in code to show us the problem directly.也许您可以在代码中提供一个示例来直接向我们展示问题。 With your provided information I got with following code example the same results根据您提供的信息,我通过以下代码示例获得了相同的结果

static void Main(string[] args)
    {
        ItemCollection<Person> list = new ItemCollection<Person> {new Person(){ FirstName = "FirstName", Name = "Name"}};
        string jsonString = JsonSerializer.Serialize(list);
        Console.WriteLine(jsonString);


        string jsonString2 =Newtonsoft.Json.JsonConvert.SerializeObject(list);
        Console.WriteLine(jsonString2);

        Console.ReadLine();
    }

[{"Name":"Name","FirstName":"FirstName"}] [{"姓名":"姓名","名":"名"}]

There is no built-in attribute corresponding to Newtonsoft's JsonObjectAttribute that will force a collection to be serialized as a JSON object.没有对应于 Newtonsoft 的JsonObjectAttribute的内置属性将强制将集合序列化为 JSON object。 1 . 1 . And there is no public equivalent to IContractResolver that can be overridden to customize serialization metadata.并且没有可以重写以自定义序列化元数据的IContractResolver的公共等效项 Thus you will need to create a custom JsonConverter to serialize the properties of your ItemCollection<T> , such as the following:因此,您需要创建一个自定义JsonConverter来序列化ItemCollection<T>的属性,例如:

[System.Text.Json.Serialization.JsonConverter(typeof(ItemCollectionJsonConverter))]
public partial class ItemCollection<T> : ICollection<T> {
    internal ItemCollection(List<T> items) { // I added this for use by the converter
        Items = items ?? throw new ArgumentNullException();
    }
    public ItemCollection() {
        Items = new List<T>();
    }
    public List<T> Items { get; set; }
    // Remainder omitted
}

public class ItemCollectionJsonConverter : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert) => GetItemCollectionValueType(typeToConvert) != null;

    public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options)
        => (JsonConverter)Activator.CreateInstance(typeof(ItemCollectionJsonConverterInner<>).MakeGenericType(GetItemCollectionValueType(type)!))!;

    static Type? GetItemCollectionValueType(Type type) =>
        (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ItemCollection<>)) ? type.GetGenericArguments()[0] : null;

    class ItemCollectionJsonConverterInner<T> : JsonConverter<ItemCollection<T>>
    {
        class ItemCollectionDTO
        {
            public List<T>? Items { get; set; }
            // Add other properties here
        }
    
        public override ItemCollection<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
            // TODO: Decide whether to throw on null
            new ItemCollection<T>((JsonSerializer.Deserialize<ItemCollectionDTO>(ref reader, options)?.Items) ?? throw new JsonException());
        
        public override void Write(Utf8JsonWriter writer, ItemCollection<T> value, JsonSerializerOptions options) =>
            JsonSerializer.Serialize(writer, new ItemCollectionDTO { Items = value.Items }, options);
    }
}

Notes:笔记:

Demo fiddle here .演示小提琴在这里


1 The list of all System.Text.Json serialization attributes is documented here . 1 此处记录了所有 System.Text.Json 序列化属性的列表。

just add object in Serialize method只需在序列化方法中添加 object

 var jsonMessageBody = JsonSerializer.Serialize<object>(model);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能在 ICollection 中引用属性? - Why can't I reference a property in an ICollection? 如何序列化ICollection <T> 作为列表 <T> 到Xml? - How to Serialize ICollection<T> as List<T> to Xml? 无法更新ICollection属性 - Can’t update ICollection property 如何使用ICollection在EF5中序列化<T> - How to Serialize in EF5 with ICollection<T> 如何序列化从List继承的类 <T> 与XML的自定义参数? - How do I serialize a class inherited from List<T> with custom parameter to XML? 如何将这个xml数组序列化为类中的属性? - How can I serialize this xml array to a property in my class? C# - 使用对基类的引用,如果我知道我的引用是对继承类的引用,我如何访问继承类的属性? - C# - with a reference to a base class, how can I access a property of the inherited class if I know that my reference is to the inherited class? 使用IXmlSerialization,如何序列化T属性? - Using IXmlSerialization, how can I serialize a T property? 枚举ICollection <T> 使用反射的类的属性 - Enumerate ICollection<T> property of class using Reflection 如何从IRecord中获取ICollection属性? - How can I get an ICollection property out of a IRecord?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM