C
C#3y ago
seahood

Mapping outgoing enums to a specific shape in Asp.net Core [Answered]

Hello! I'm trying to find a way to take any outgoing enums in DTOs from an ASP.NET Core API, and map them into a specific shape before they head down the wire. I have an Enumeration class that's used by an existing mapper to map enum values to.
public class Enumeration
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Enumeration
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
I'm using
services.AddControllers().AddJsonOptions(opts => { /* I guess some enum mapping converter should go here */ })
services.AddControllers().AddJsonOptions(opts => { /* I guess some enum mapping converter should go here */ })
I've tried looking at implementing a JsonConverter and it almost works, but falls down when it encounters a nullable enum. There's a built in JsonEnumStringConverter but that only maps the enum to it's corresponding string. Current output example from an API endpoint:
{
"someEnum": 0
}
{
"someEnum": 0
}
Expected output example:
{
"someEnum": {
"Id": 0,
"Name": "SomeEnum",
"Description": "SomeEnum"
}
}
{
"someEnum": {
"Id": 0,
"Name": "SomeEnum",
"Description": "SomeEnum"
}
}
I hope that makes sense? I think I need to find a way to handle the nullable enum situation (or there's an easier way and i'm just going about this all wrong). It's an annoying requirement of this API migration that i'm doing
5 Replies
seahood
seahoodOP3y ago
This is as far as I got with the JsonConverter implementation that almost works:
public class ApiEnumConverter : JsonConverter<Enum>
{
public override Enum Read(
ref Utf8JsonReader reader,
Type objectType,
JsonSerializerOptions options)
{
var type = JsonSerializer.Deserialize<Enumeration>(reader.GetString());
var underlyingType = objectType.IsNullable()
? Nullable.GetUnderlyingType(objectType)
: objectType;
return (Enum)Enum.Parse(underlyingType, type.Id.ToString(CultureInfo.InvariantCulture));
}

public override void Write(
Utf8JsonWriter writer,
Enum value,
JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, EnumerationMapper.Map(value));


public override bool CanConvert(Type objectType)
{
if (objectType.IsEnum)
return true;

var nullableEnumType = Nullable.GetUnderlyingType(objectType);
return nullableEnumType != null && nullableEnumType.IsEnum;
}
}
public class ApiEnumConverter : JsonConverter<Enum>
{
public override Enum Read(
ref Utf8JsonReader reader,
Type objectType,
JsonSerializerOptions options)
{
var type = JsonSerializer.Deserialize<Enumeration>(reader.GetString());
var underlyingType = objectType.IsNullable()
? Nullable.GetUnderlyingType(objectType)
: objectType;
return (Enum)Enum.Parse(underlyingType, type.Id.ToString(CultureInfo.InvariantCulture));
}

public override void Write(
Utf8JsonWriter writer,
Enum value,
JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, EnumerationMapper.Map(value));


public override bool CanConvert(Type objectType)
{
if (objectType.IsEnum)
return true;

var nullableEnumType = Nullable.GetUnderlyingType(objectType);
return nullableEnumType != null && nullableEnumType.IsEnum;
}
}
Mayor McCheese
Why not just use the enumeration class, and ignore the enum entirely?
seahood
seahoodOP3y ago
it's a huge legacy project with thousands of things depending on enums being the correct type in the DTOs, would take forever to change everything i think i've resolved it by convincing it to use AddNewtonsoftJson() and using the converter we originally had
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Accord
Accord3y ago
✅ This post has been marked as answered!

Did you find this page helpful?