如何从使用在启动时全局设置的JsonStringEnumConverter中排除模型的枚举属性?

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

我正在使用最新的.NET Core 3.1.1和以前使用System.Text.JsonNewtonsoft.Json开发ASP.NET Core应用程序。按照Microsoft Migration guide的建议我已完成更改。另外,由于我的大多数枚举都需要序列化为String,因此我已将Startup.cs ConfigureServices配置为全局使用JsonStringEnumConverter

public void ConfigureServices(IServiceCollection services)
{
    // lines omitted for brevity

    services.AddControllers()
                .AddJsonOptions(options =>
                    {
                        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
                        options.JsonSerializerOptions.IgnoreNullValues = true;
                        options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
                    });
}

但是最近,在发布之后,我们意识到通过我们的API在json中只给出了几个枚举作为数字。由于这些API是在外部使用的,因此将数字更改为字符串可能是一项昂贵的工作。

因此,有没有办法忽略某些枚举属性的通用性,例如带有[JsonIgnore]属性的修饰?

c# json asp.net-core .net-core system.text.json
1个回答
0
投票

JsonStringEnumConverter实际上是JsonStringEnumConverter的子类。它为序列化过程中遇到的每种具体的JsonConverterFactory类型生成一个特定的JsonConverterFactory,进而将特定的JsonConverterEnum类型序列化为字符串。

如果您不希望将某些特定的JsonConverterEnum type序列化为字符串,则可以使用enum并创建自己的转换器工厂来装饰enum,但防止enum类型转换如下:

decorator pattern

然后在以下选项中使用它:

JsonStringEnumConverter

注意:

  • 如果要维护将枚举类型序列化为整数的列表很不方便,则可以使用某些自定义enum将枚举类型序列化为整数,然后从public class OptOutJsonConverterFactory : JsonConverterFactoryDecorator { readonly HashSet<Type> optOutTypes; public OptOutJsonConverterFactory(JsonConverterFactory innerFactory, params Type [] optOutTypes) : base(innerFactory) => this.optOutTypes = optOutTypes.ToHashSet(); public override bool CanConvert(Type typeToConvert) => base.CanConvert(typeToConvert) && !optOutTypes.Contains(typeToConvert); } public class JsonConverterFactoryDecorator : JsonConverterFactory { readonly JsonConverterFactory innerFactory; public JsonConverterFactoryDecorator(JsonConverterFactory innerFactory) { if (innerFactory == null) throw new ArgumentNullException(nameof(innerFactory)); this.innerFactory = innerFactory; } public override bool CanConvert(Type typeToConvert) => innerFactory.CanConvert(typeToConvert); public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => innerFactory.CreateConverter(typeToConvert, options); } 中排除带有该属性的类型。 >

  • 需要装饰图案,因为options.Converters.Add(new OptOutJsonConverterFactory(new JsonStringEnumConverter(), // Add here all enum types to serialize as integers: typeof(SomeEnumNotToSerializeAsAString) //, ... )); 已密封。

  • 模型小提琴#1 attribute

或者,如果您不希望将某些特定的CanConvert(CanConvert(Type typeToConvert) property

序列化为字符串,则可以使用JsonStringEnumConverter将转换器应用于该属性,而忽略传入的here并生成默认值序列化:
enum

并按如下所示将其应用于您的模型:

JsonConverterAttribute

注意:

  • 此解决方案利用了JsonConverterAttribute

    1. JsonSerializerOptions应用于属性。
    2. 已将转换器添加到Converters集合。
    3. [/// <summary> /// Apply this converter to a property to force the property to be serialized with default options. /// This converter can ONLY be applied to a property; setting it in options or on a type may cause a stack overflow exception! /// </summary> /// <typeparam name="T">the property's declared return type</typeparam> public class SerializePropertyAsDefaultConverter<T> : JsonConverter<T> { public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return JsonSerializer.Deserialize<T>(ref reader); // Ignore the incoming options! } public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value); // Ignore the incoming options! } } 应用于自定义值类型或POCO。
  • 模型小提琴#2 public class Model { public StringEnum StringEnum { get; set; } [JsonConverter(typeof(SerializePropertyAsDefaultConverter<SomeEnumNotToSerializeAsAString>))] public SomeEnumNotToSerializeAsAString SomeEnumNotToSerializeAsAString { get; set; } } 。>>

© www.soinside.com 2019 - 2024. All rights reserved.