I have added a custom attribute to some enum values (to give them a screen friendly string value). I am trying to build a list of SelectListItems for use on an MVC page, but I am running into trouble accessing the custom attribute.
My enum looks like this.
public enum MyEnum
{
[StringValue("None")] None = 0,
[StringValue("First Value")] FirstValue = 1,
[StringValue("Second Value")] SecondValue = 2
}
The attribute looks like this.
public class StringValueAttribute : Attribute
{
public StringValueAttribute(string value)
{
this.StringValue = value;
}
public string StringValue { get; protected set; }
}
I created a helper class so that I can easily access the StringValue attribute from an instance of the Enum.
public static string GetStringValue(this Enum value)
{
Type type = value.GetType();
FieldInfo fieldInfo = type.GetField(value.ToString());
StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
return attribs != null && attribs.Length > 0 ? attribs[0].StringValue : null;
}
I could call it like this.
MyEnum test = MyEnum.FirstValue;
string stringValue = test.GetStringValue();
Finally, onto the code I am stuck with. I can loop over the Enum Values easily, but the values are not instances of MyEnum so I cannot call my helper function. And when I try to access the FieldInfo it always returns null. Here is what I have so far.
public static List<SelectListItem> GetFlagsSelectList<T>(int? selectedValue)
{
List<SelectListItem> items = new List<SelectListItem>();
foreach (int value in Enum.GetValues(typeof(T)))
{
items.Add(new SelectListItem
{
Text = Enum.GetName(typeof(T), value),
Value = value.ToString(),
Selected = selectedValue.HasValue && selectedValue.Value == value
});
}
return items;
}
Is it possible to access the custom attribute within the foreach loop?
EDIT:
I think I asked this unclearly. I would like to access the custom attribute inside the foreach loop. Calling Enum.GetName(typeof(T), value) simply returns the name of the property (e.g. FirstValue) which I do NOT want.
I would like to do something like:
foreach (int value in Enum.GetValues(typeof(T)))
{
string name = Enum.ToObject(typeof (T), value).GetStringValue();
}
But T could be any type so I can't call my GetStringValue() method there.
I have tried doing this:
foreach (int value in Enum.GetValues(typeof(T)))
{
FieldInfo fieldInfo = typeof(T).GetField(value.ToString());
StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
string name = attribs != null && attribs.Length > 0 ? attribs[0].StringValue : Enum.GetName(typeof(T), value),;
items.Add(new SelectListItem
{
Text = name,
Value = value.ToString(),
Selected = selectedValue.HasValue && selectedValue.Value == value
});
}
But I always get an exception because the FieldInfo object always returns null.
Try