【问题标题】:Dynamically Ignore property on writing object based on another property with System.Text.Json基于 System.Text.Json 的另一个属性动态忽略写入对象的属性
【发布时间】:2021-09-08 10:23:20
【问题描述】:

如果另一个属性包含某个值,我需要能够序列化一个类并动态忽略某些属性(而不是将它们写到 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;}
}

如果我们在Type1Types 列表中有一个字符串,我希望将该属性序列化为 JSON 字符串,PropertyValidForType2PropertyValidForType2 也是如此。

它们将是许多不需要序列化的属性,因此能够使用属性执行此操作将是有益的。我知道可以添加 [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 属性,因为列表中不包含Type2

【问题讨论】:

  • 你能解释一下,是Type属性依赖于其他字段的值,还是PropertyValidForType1/2/3值依赖于Types列表?
  • @IvanKhorin PropertyValidForType1/2/3 取决于类型列表中的特定类型。

标签: c# .net system.text.json


【解决方案1】:

我无法如你所愿地解决你的问题,这个功能看起来没有在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);
    }
}

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

// 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",
};
// ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-11
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 2023-02-01
    相关资源
    最近更新 更多