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.
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.