C
C#2w ago
James.

✅ Enums as strings on AspNetCore controller .NET 9

I have added this enum
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum Locale
{
[JsonStringEnumMemberName("ar_AE")]
ArabicUae,
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum Locale
{
[JsonStringEnumMemberName("ar_AE")]
ArabicUae,
In swagger it shows as expected
No description
6 Replies
James.
James.OP2w ago
However when you send a request it fails because of model validation
[HttpPost("/authorize", Name = "Authorize")]
[Consumes("application/x-www-form-urlencoded")]
[ProducesResponseType<AuthorizeResponse>(StatusCodes.Status200OK)]
public async Task<IActionResult> Authorize(
[FromForm] string login,
[FromForm] string password,
[FromForm] Locale? locale,
CancellationToken cancellationToken)
[HttpPost("/authorize", Name = "Authorize")]
[Consumes("application/x-www-form-urlencoded")]
[ProducesResponseType<AuthorizeResponse>(StatusCodes.Status200OK)]
public async Task<IActionResult> Authorize(
[FromForm] string login,
[FromForm] string password,
[FromForm] Locale? locale,
CancellationToken cancellationToken)
James.
James.OP2w ago
No description
Sehra
Sehra2w ago
form data does not use encode using json
Sehra
Sehra2w ago
you want something like [TypeConverter(typeof(EnumMemberConverter<Locale>))] and [EnumMember(Value = "ae_AE")] see https://stackoverflow.com/a/68625960
Stack Overflow
Can't map [FromForm] enum with [EnumMember] in asp.net core api 3.1
I have an enum with EnumMemberAttribute specified for its values: public enum HireStrategy { [EnumMember(Value = "30-days")] Days30, [EnumMember(Value = "60-days")] ...
Sehra
Sehra2w ago
but for localization there is already support in aspnet to grab it from various places https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-9.0
Globalization and localization in ASP.NET Core
Learn how ASP.NET Core provides services and middleware for localizing content into different languages and cultures.
James.
James.OP2w ago
Thanks man, sorted the problem instantly. Added support to the converter to take into account JsonStringEnumMemberNameAttribute, so that this converted and json converter will convert in the same way across my app. Thanks but no thanks, I have a spec I need to follow 🙂 For any potential future readers here's my solution:
[TypeConverter(typeof(StringEnumConverter<Locale>))]
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum Locale
{
[JsonStringEnumMemberName("ar_AE")]
ArabicUae,
}
[TypeConverter(typeof(StringEnumConverter<Locale>))]
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum Locale
{
[JsonStringEnumMemberName("ar_AE")]
ArabicUae,
}
public class StringEnumConverter<T> : TypeConverter where T : struct, Enum
{
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value is string stringValue)
{
var type = typeof(T);
foreach (var field in type.GetFields())
{
var attr = field.GetCustomAttribute<JsonStringEnumMemberNameAttribute>();
if (attr != null && string.Equals(attr.Name, stringValue, StringComparison.OrdinalIgnoreCase))
{
return (T)Enum.Parse(type, field.Name);
}
}

if (Enum.TryParse<T>(stringValue, true, out var result))
{
return result;
}
}

throw new ArgumentException($"Cannot convert {value} to {typeof(T).Name}");
}
}
public class StringEnumConverter<T> : TypeConverter where T : struct, Enum
{
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value is string stringValue)
{
var type = typeof(T);
foreach (var field in type.GetFields())
{
var attr = field.GetCustomAttribute<JsonStringEnumMemberNameAttribute>();
if (attr != null && string.Equals(attr.Name, stringValue, StringComparison.OrdinalIgnoreCase))
{
return (T)Enum.Parse(type, field.Name);
}
}

if (Enum.TryParse<T>(stringValue, true, out var result))
{
return result;
}
}

throw new ArgumentException($"Cannot convert {value} to {typeof(T).Name}");
}
}

Did you find this page helpful?