获取.NET Core JsonSerializer来序列化私有成员。

问题描述 投票:0回答:1

我有一个班级,有一个私人 List<T> 属性,而我想通过使用 JsonSerializer. 使用 JsonPropertyAttribute 似乎在.NET Core中并不支持。那么如何才能让我的私有列表属性序列化呢?

我使用System.Text.Json来实现。

c# .net-core jsonserializer system.text.json
1个回答
4
投票

似乎System.Text.Json不支持私有属性序列化。

https:/docs.microsoft.comtr-trdotnetstandardserializationsystem-text-json-migrat-from-newtonsoft-how-to#internaland-privateproperty-setters-and-getters。

但正如微软的文档所说,你可以用自定义的转换器来实现。

https:/www.thinktecture.comenasp-netaspnet-core-3-0-custom-jsonconverter-for-the-new-system_text_json

用于序列化的代码片段。

  public class Category
    {
        public Category(List<string> names)
        {
            this.Names1 = names;
        }

        private List<string> Names1 { get; set; }
        public string Name2 { get; set; }
        public string Name3 { get; set; }
    }


 public class CategoryJsonConverter : JsonConverter<Category>
    {
        public override Category Read(ref Utf8JsonReader reader,
                                      Type typeToConvert,
                                      JsonSerializerOptions options)
        {
                       var name = reader.GetString();

            var source = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(name);

            var category = new Category(null);

            var categoryType = category.GetType();
            var categoryProps = categoryType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (var s in source.Keys)
            {
                var categoryProp = categoryProps.FirstOrDefault(x => x.Name == s);

                if (categoryProp != null)
                {
                    var value = JsonSerializer.Deserialize(source[s].GetRawText(), categoryProp.PropertyType);

                    categoryType.InvokeMember(categoryProp.Name,
                        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance,
                        null,
                        category,
                        new object[] { value });
                }
            }

            return category;
        }

        public override void Write(Utf8JsonWriter writer,
                                   Category value,
                                   JsonSerializerOptions options)
        {
            var props = value.GetType()
                             .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                             .ToDictionary(x => x.Name, x => x.GetValue(value));

            var ser = JsonSerializer.Serialize(props);

            writer.WriteStringValue(ser);
        }
    }

static void Main(string[] args)
    {
        Category category = new Category(new List<string>() { "1" });
        category.Name2 = "2";
        category.Name3 = "3";

        var opt = new JsonSerializerOptions
        {
            Converters = { new CategoryJsonConverter() },
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
        };

        var json = JsonSerializer.Serialize(category, opt);

        var obj = JsonSerializer.Deserialize<Category>(json, opt);

        Console.WriteLine(json);
        Console.ReadKey();
    }

结果:

"{\"Names1\":[\"1\"],\"Name2\":\"2\",\"Name3\":\"3\"}"
© www.soinside.com 2019 - 2024. All rights reserved.