首页 > 解决方案 > 基于 System.Text.Json 的另一个属性动态忽略写入对象的属性

问题描述

如果另一个属性包含某个值,我需要能够序列化一个类并动态忽略某些属性(而不是将它们写到 JSON 中)。

所以想象下面的类:

public class MyClass
{
    public List<string> Types { get; set; }
    public string PropertyValidForType1 {get; set;}
    public string PropertyValidForType2 {get; set;}
    public string PropertyValidForType2 {get; set;}
}

如果我们在Types列表中有一个字符串,Type1我希望将该属性序列化为 JSON 字符串,对于PropertyValidForType2和 也是如此PropertyValidForType2

它们将是许多不需要序列化的属性,因此能够使用属性执行此操作将是有益的。我知道可以添加[JsonIgnore]属性,但这些不允许有条件地忽略属性。

这是我想了解的一个例子

public class MyClass
{
    public List<string> Types { get; set; }

    [IncludeIfListIncludes(typeof(Types), "Type1")]
    public string PropertyValidForType1 {get; set;}

    [IncludeIfListIncludes(typeof(Types), "Type2")]
    public string PropertyValidForType2 {get; set;}

    [IncludeIfListIncludes(typeof(Types), "Type2")]
    public string PropertyValidForType3 {get; set;}
}

var c = new MyClass
{
    Types = new List<string> { "Type1", "Type3" },
    PropertyValidForType1 = "A",
    PropertyValidForType2 = "B",
    PropertyValidForType3 = "C",
}

var jsonString = JsonSerializer.Serialize(weatherForecast);

Console.WriteLine(jsonString);
// Expected Output: { Types : [ "Type1", "Type3" ], PropertyValidForType1: "A", PropertyValidForType3: "C" } 

上面的示例将跳过PropertyValidForType2属性,因为列表中不包含 a Type2

标签: c#.netsystem.text.json

解决方案


我无法按照您的意愿解决您的问题,此功能看起来没有在 中实现System.Text.Json,但您可以通过实现派生自JsonConverter().

using System.Text.Json;
using System.Text.Json.Serialization;

public static class Program
{
    public class IMyClassConverter : JsonConverter<MyClass>
    {
        public override MyClass? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return null;            
        }

        public override void Write(Utf8JsonWriter writer, MyClass value, JsonSerializerOptions options)
        {
            writer.WriteStartObject();

            JsonSerializer.Serialize(writer, value.Types);

            if (value.Types.Contains("Type1")) JsonSerializer.Serialize(writer, value.PropertyValidForType1);
            if (value.Types.Contains("Type2")) JsonSerializer.Serialize(writer, value.PropertyValidForType2);
            if (value.Types.Contains("Type3")) JsonSerializer.Serialize(writer, value.PropertyValidForType3);

            writer.WriteEndObject();
        }
    }

    public class MyClass
    {
        public List<string> Types { get; set; }
        public string PropertyValidForType1 { get; set; }
        public string PropertyValidForType2 { get; set; }
        public string PropertyValidForType3 { get; set; }
    }

    public static void Main()
    {
        var c = new MyClass
        {
            Types = new List<string> { "Type1", "Type3" },
            PropertyValidForType1 = "A",
            PropertyValidForType2 = "B",
            PropertyValidForType3 = "C",
        };

        var options = new JsonSerializerOptions();
        options.Converters.Add(new IMyClassConverter());
        options.WriteIndented = true;

        var jsonString = JsonSerializer.Serialize(c, options);

        System.Console.WriteLine(jsonString);
    }
}

你必须这样挖掘,也许创建一些<T>类等等,我的业务逻辑在这个例子中很差,但它有效。PS您也可以使用接口,但是如果不将对象转换为接口,我无法实现这一点。

// CODE
public interface IMyClass
{
    List<string> Types { get; set; }
    string PropertyValidForType1 { get; set; }
    string PropertyValidForType2 { get; set; }
    string PropertyValidForType3 { get; set; }
}

// ...
public class MyClass : IMyClass
// ...
IMyClass c = new MyClass
{
    Types = new List<string> { "Type1", "Type3" },
    PropertyValidForType1 = "A",
    PropertyValidForType2 = "B",
    PropertyValidForType3 = "C",
};
// ...

推荐阅读