Open Closed

Change enum json serialization in response #6056


User avatar
0

Hi, I'm trying to globally configure json serialization options to return enum properties as strings in response body. I tried to configure AbpSystemTextJsonSerializerOptions and AbpSystemTextJsonSerializerModifiersOptions, but the one way it worked using [JsonConvert(typeof(...))] atrribute. We want to find a way to make it work without attribute usage. Is it possible in current version or maybe I missed something?

  • ABP Framework version: v7.4.0
  • UI Type: Angular
  • Database System: MongoDB
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

6 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    HI,

    You can check this: https://github.com/abpframework/abp/issues/13010

  • User Avatar
    0

    HI, Liangshiwei Yea, I tried to configure Mvc.JsonOptions as well, but still I need to use JsonConverter attribute. I'm wonder if it is possible to achieve this without specifying attribute on each enum property.

    You can check this: https://github.com/abpframework/abp/issues/13010

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Could you provide the full steps to reproduce the problem? I will check it. thanks

  • User Avatar
    0

    Hi,

    Could you provide the full steps to reproduce the problem? I will check it. thanks

    Sure,

    1. Configure Mvc.JsonOptions via Configure method (HttpApi.Host module)
    2. Dto
    3. Response

    And this is how response look like with [JsonConvert(typeof(JsonStringEnumConverter))] attribute for SubscriptionType field

    Our goal is to achive this without attribute specification

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You need to remove the AbpStringToEnumFactory

    Just an example:

    public class EnumToStringConverterFactory : JsonConverterFactory
    {
        public override bool CanConvert(Type typeToConvert)
        {
            return typeToConvert.IsEnum;
        }
    
        public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
        {
            return (JsonConverter)Activator.CreateInstance(
                typeof(MyEnumToStringConverter<>).MakeGenericType(typeToConvert),
                BindingFlags.Instance | BindingFlags.Public,
                binder: null,
                new object?[] { },
                culture: null)!;
        }
    }
    
    public class MyEnumToStringConverter<T> : JsonConverter<T>
        where T : struct, Enum
    {
        public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return Enum.Parse<T>(reader.GetString()!);
        }
    
        public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value.ToString());
        }
    }
    
    Configure<AbpSystemTextJsonSerializerOptions>(options =>
    {
        var stringToEnumFactory = options.JsonSerializerOptions.Converters.Single(x => x.GetType() == typeof(AbpStringToEnumFactory));
        options.JsonSerializerOptions.Converters.Remove(stringToEnumFactory);
        options.JsonSerializerOptions.Converters.Add(new EnumToStringConverterFactory());
    });
    
    Configure<JsonOptions>(options =>
    {
        var stringToEnumFactory = options.JsonSerializerOptions.Converters.Single(x => x.GetType() == typeof(AbpStringToEnumFactory));
        options.JsonSerializerOptions.Converters.Remove(stringToEnumFactory);
        options.JsonSerializerOptions.Converters.Add(new EnumToStringConverterFactory());
    });
    

  • User Avatar
    0

    Hi,

    You need to remove the AbpStringToEnumFactory

    Just an example:

    public class EnumToStringConverterFactory : JsonConverterFactory 
    { 
        public override bool CanConvert(Type typeToConvert) 
        { 
            return typeToConvert.IsEnum; 
        } 
     
        public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) 
        { 
            return (JsonConverter)Activator.CreateInstance( 
                typeof(MyEnumToStringConverter<>).MakeGenericType(typeToConvert), 
                BindingFlags.Instance | BindingFlags.Public, 
                binder: null, 
                new object?[] { }, 
                culture: null)!; 
        } 
    } 
     
    public class MyEnumToStringConverter<T> : JsonConverter<T> 
        where T : struct, Enum 
    { 
        public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 
        { 
            return Enum.Parse<T>(reader.GetString()!); 
        } 
     
        public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) 
        { 
            writer.WriteStringValue(value.ToString()); 
        } 
    } 
     
    Configure<AbpSystemTextJsonSerializerOptions>(options => 
    { 
        var stringToEnumFactory = options.JsonSerializerOptions.Converters.Single(x => x.GetType() == typeof(AbpStringToEnumFactory)); 
        options.JsonSerializerOptions.Converters.Remove(stringToEnumFactory); 
        options.JsonSerializerOptions.Converters.Add(new EnumToStringConverterFactory()); 
    }); 
     
    Configure<JsonOptions>(options => 
    { 
        var stringToEnumFactory = options.JsonSerializerOptions.Converters.Single(x => x.GetType() == typeof(AbpStringToEnumFactory)); 
        options.JsonSerializerOptions.Converters.Remove(stringToEnumFactory); 
        options.JsonSerializerOptions.Converters.Add(new EnumToStringConverterFactory()); 
    }); 
    

    Thanks a lot, removing AbpStringToEnumFactory solved my problem)

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11