Joel Wahlund
Joel Wahlund

Reputation: 271

How to get enum from model into view with displayfor

I have trouble getting a view populated by a enum value from a model correctly.

I tried reading up from this thread to help me out with a htmlhelper, with no prevail: How find the enum name for corresponding value and use it in DisplayFor?

public static class HtmlExtensions
{
    public static IHtmlString DisplayEnumFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, int>> ex, Type enumType)
    {
        var value = (int)ModelMetadata.FromLambdaExpression(ex, html.ViewData).Model;
        string enumValue = Enum.GetName(enumType, value);
        return new HtmlString(html.Encode(enumValue));
    }
}

But alas, it doesn't work. And I get this message:

CS0266: Cannot implicitly convert type 'HiltiHaninge.Models.Discplines' to 'int'. An explicit conversion exists (are you missing a cast?)

I've tried with my best effort not to make it to a int, but a string representation of that value that the model contains. The view:

@model HiltiHaninge.Models.CellEntity
@using HiltiHaninge.Helpers

@{
ViewBag.Title = "Ta bort pass " + @Html.DisplayFor(model => model.Id) + ", på " + @Html.DisplayFor(model => model.Day);
}

<h2>@ViewBag.Title</h2>

<h3>Är du säker på att du vill radera inlägget?</h3>
<fieldset>
<legend>Pass @Html.DisplayFor(model => model.Id)</legend>

<div class="display-label">
    <p class="text_without_indent">Tid från: (TT-MM)</p>
</div>
<div class="display-field">
    @Html.DisplayFor(model => model.TimeFromHour)
    @Html.DisplayFor(model => model.TimeFromMinute)
</div>

<div class="display-label">
    <p class="text_without_indent">Tid till: (TT-MM)</p>
</div>
<div class="display-field">
    @Html.DisplayFor(model => model.TimeToHour)
    @Html.DisplayFor(model => model.TimeToMinute)
</div>

<div class="display-label">
     <p class="text_without_indent">@Html.DisplayNameFor(model => model.Discipline)</p>
</div>
<div class="display-field">
    @Html.DisplayEnumFor(model => model.Discipline, typeof(HiltiHaninge.Models.Discplines))
</div>

<div class="display-label">
     <p class="text_without_indent">@Html.DisplayNameFor(model => model.Level)</p>
</div>
<div class="display-field">
    @Html.DisplayEnumFor(model => model.Level, typeof(HiltiHaninge.Models.Levels))
</div>

<div class="display-label">
    <p class="text_without_indent">@Html.DisplayNameFor(model => model.Coach)</p>
</div>
<div class="display-field">
    @Html.DisplayFor(model => model.Coach)
</div>

</fieldset>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
<p>
    <input type="submit" value="Ta bort" /> |
    @Html.ActionLink("Tillbaka till listan", "Index")
</p>
}

Anyone got any ideas, I'd appreciate it.

Upvotes: 3

Views: 11983

Answers (3)

Click Ok
Click Ok

Reputation: 8852

This is broken and will not be fixed.

But you can use this workaround.

Upvotes: 3

Ste W
Ste W

Reputation: 133

If you simply want to output the enum value as a string then you can just do this:

<div class="display-field">
    @Enum.GetName(typeof(HiltiHaninge.Models.Discplines), Model.Discipline)
</div>

Upvotes: 4

Ste W
Ste W

Reputation: 133

However...

If you simply want to fix your displayFor method then you can make the type generic instead of int, e.g.

public static IHtmlString DisplayEnumFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> ex, Type enumType) where TValue : struct, IConvertible
{
    var value = (int)ModelMetadata.FromLambdaExpression(ex, html.ViewData).Model;
    string enumValue = Enum.GetName(enumType, value);
    return new HtmlString(html.Encode(enumValue));
}

Also I have added what is typically used as a constraint for enums. see: Create Generic method constraining T to an Enum

Upvotes: 2

Related Questions