Human readable strings from enums in DTO's

I am wondering if there is a way to get a human readable string into the DTO from my enums. In my backend project I use an Attribute I made to handle human readable strings, can that be leveraged somehow?

I use Enums.NET to map from strings to enum values, because I am using a very poorly implemented external API, which uses string values.

First, I define a custom handler for my external API (done once for whole API):

[AttributeUsage(AttributeTargets.Field)]
public class ExternalAttribute : Attribute
{
    public string External { get; }

    public ExternalAttribute(string external)
    {
        External = external;
    }
}

public static readonly EnumFormat ExternalFormat =
    Enums.RegisterCustomEnumFormat(member => member.Attributes.Get<ExternalAttribute>()?.External);

// Used to handle external and name values of enum strings
public static EnumFormat[] AllEnumFormats =>
    new EnumFormat[] { ExternalFormat, EnumFormat.Name };

Then following shows how I use it to map back and forward between for one of my enum types:

public enum ActiveInactiveDeletedStatus
{
    [External("A")] Active,
    [External("I")] Inactive,
    [External("D")] Deleted
};

public static ActiveInactiveDeletedStatus ToActiveInactiveDeletedStatus(string value) =>
    Enums.Parse<ActiveInactiveDeletedStatus>(value, ignoreCase: true, AllEnumFormats);

public static string FromActiveInactiveDeletedStatus(ActiveInactiveDeletedStatus value) =>
    value.AsString(ExternalFormat)!;

I tried other approaches, but I like having the string defined in the enum.

See the documentation and samples from Enum.NET for other techniques.

Hope it helps.

1 Like

If you just want to serialize a custom string in place of an enum you can use EnumMember, e.g;

[DataContract]
public enum Day
{
    [EnumMember(Value = "MON")]
    Monday,
    [EnumMember(Value = "TUE")]
    Tuesday,
    [EnumMember(Value = "WED")]
    Wednesday,
    [EnumMember(Value = "THU")]
    Thursday,
    [EnumMember(Value = "FRI")]
    Friday,
    [EnumMember(Value = "SAT")]
    Saturday,
    [EnumMember(Value = "SUN")]
    Sunday,            
}

Also have a look at how https://github.com/Chatham/ServiceStack.Text.EnumMemberSerializer is customizing ServiceStack.Text to serialize custom enums by specifying JsConfig<T>.SerializeFn and JsConfig<T>.DeSerializeFn handlers.