I want to display an Index style View featuring an HTML table that I populate from my @model
, a List<MyViewModel>
.
The MyViewModel
class has a property called Status, which is a custom enum I've defined like so:
public enum MarketingEmailStatus
{
Queued,
Sending,
Sent
}
When I attempt to display that property in my View like so ...
...
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayForModel(modelItem => item.Status)
</td>
...
I get an error (both in Intellisense and at run time):
Cannot convert lambda expression to type 'object' because it is not a delegate type
I tried to do item.Status.ToString()
to no avail.
No doubt, I could probably take an alternative approach (i.e., just change the ViewModel to represent Status as a string and resolve this prior to sending to the view), but this feels like such a simple scenario that it should be possible. And yet after an hour of searching I've not found any solutions (other than those related to DropDownLists for which there seems to be some @Html
helper methods available.)
I see two problems with directly using @item.Status:
It won't respect the "display values" of those enums e.g. instead of "Code Sample", it would show "CodeSample".
It doesn't take into account the localization.
This looks like a very promising solution for such scenarios, in my opinion.
You can obviously just use the extension methods if point 2 is not your concern as below:
public static class EnumExtensions
{
public static string GetDisplayName(this Enum enumValue)
{
FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
var displayAttribute = fi.CustomAttributes.FirstOrDefault(c => c.AttributeType == typeof(DisplayAttribute));
if (displayAttribute == null) return enumValue.ToString();
return displayAttribute.NamedArguments.FirstOrDefault(a => a.MemberName == "Name").TypedValue.Value.ToString();
}
}