How is it possible to use the string
value of an Enum
to return all objects with a parameter that matches?
With this Enum for Language and using System.Runtime.Serialization;
in the Class:
public enum Lcid
{
[EnumMember(Value = "en-US")]en_US,
[EnumMember(Value = "en-AU")]en_AU
}
And another class that holds the Enum value like so:
public class Application
{
public int Id { get; set; }
public string Name { get; set; }
public string Publisher { get; set; }
public Lcid Lcid { get; set; }
}
I have tried constructing a HttpGet method like:
[HttpGet("lcid/{lcid}")]
public async Task<ActionResult><IEnumerable<Application>>> GetApplicationByLcid([FromRoute]string lcid)
{
var applications = _context.Application.Where(a => a.Language.ToString() == lcid);
if (applications.Count() == 0)
{
return NotFound();
}
return await applications.ToListAsync();
}
Unfortunately, that didn't work.
I have also tried to use additional code within the GetApplicationByLcid
method:
[HttpGet("lcid/{lcid}")]
public async Task<ActionResult><IEnumerable<Application>>> GetApplicationByLcid([FromRoute]string lcid)
{
int ValueToFind = Lcid["lcid"];
var applications = _context.Application.Where(a => a.Lcid == ValueToFind);
if (applications.Count() == 0)
{
return NotFound();
}
return await applications.ToListAsync();
}
That doesn't work either. I have been trying to work this out using just a basic CLI application without much luck either. I would have to know the value of the string and convert it out using a switch statement in CLI testing:
public static int x;
static void Main(string[] args)
{
string lcid = "en-US";
switch(lcid)
{
case "en-AU":
x = (int)Lcid.en_AU;
break;
case "en-US":
x = (int)Lcid.en_US;
break;
}
Console.WriteLine(x);
}
This would return 0
, but it's a lot of code to just get the value, and I'd still have to be able to index that against all the Application
object in my DB that have the Enum value there.
In Program.cs
I have enabled Enum to convert the output to string by adding:
builder.Services.AddControllers().AddJsonOptions(x =>
{
x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
Could my original code be re-written so to show how to find all Application
object that have a specific Lcid value for Lcid from the Enum?
You have a little problem with hyphen and underscore conversion, thats because Custom Attriubutes are not easily accessed. The 'hacky' way to achieve it is simply
var applications = _context.Application.Where(a => a.Language.ToString().Replace("_","-") == lcid);
The nice way to do it could be a extension method to read the Custom Atribute from Enums:
public static class EnumExtensions
{
public static T GetValueFromEnumMember<T>(string value) where T: Enum
{
var type = typeof(T);
foreach (var field in type.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field,
typeof(EnumMemberAttribute)) as EnumMemberAttribute;
if (attribute != null)
{
if (attribute.Value == value)
return (T)field.GetValue(null);
}
else
{
if (field.Name == value)
return (T)field.GetValue(null);
}
}
throw new ArgumentException($"unknow value: {value}");
}
}
and use it like this:
var applications = _context.Application.Where(a => a.Language == EnumExtensions.GetValueFromEnumMember<Lcid>(lcid));