Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

DisplayFor doesn't retrieve enum values #2430

Closed
weitzhandler opened this issue Apr 22, 2015 · 15 comments
Closed

DisplayFor doesn't retrieve enum values #2430

weitzhandler opened this issue Apr 22, 2015 · 15 comments

Comments

@weitzhandler
Copy link

The enum support is indeed a great add, thanks for implementing it.

Anyway, I've found something missing about it, when calling DisplayFor(model => model.EnumField) doesn't render the enum value, it won't retrieve the value from resources, but it will render the original value:

public enum MaritalStatus : byte
{
  [Display(ResourceType = typeof(PersonResx), Name = "MaritalStatus_None")]
  None,
  [Display(ResourceType = typeof(PersonResx), Name = "MaritalStatus_Single")]
  Single,
  [Display(ResourceType = typeof(PersonResx), Name = "MaritalStatus_Married")]
  Married,
  [Display(ResourceType = typeof(PersonResx), Name = "MaritalStatus_Divorced")]
  Divorced,
  [Display(ResourceType = typeof(PersonResx), Name = "MaritalStatus_Widowed")]
  Widowed
}

The above works just fine with @Html.EnumDropDownListFor(model => model.MaritalStatus), but doesn't work for DisplayFor.

Please fix this.

@ZerglingX6
Copy link

To solve the problem Temporarily。add a shared view of enum。
just like this:

@model Enum

@if (EnumHelper.IsValidForEnumHelper(ViewData.ModelMetadata))
{
    // Display Enum using same names(from [Display] attributes) as in editors
    string displayName = null;
    foreach (SelectListItem item in EnumHelper.GetSelectList(ViewData.ModelMetadata, (Enum)Model))
    {
        if (item.Selected)
        {
            displayName = item.Text ?? item.Value;
        }
    }

    // Handle the unexpected case that nothing is selected
    if (String.IsNullOrEmpty(displayName))
    {
        if (Model == null)
        {
            displayName = String.Empty;
        }
        else
        {
            displayName = Model.ToString();
        }
    }
    @Html.DisplayTextFor(model => displayName)
}
else
{
    // This Enum type is not supported. Fall back to the text.
    @Html.DisplayTextFor(model => model)
}

@fschmied
Copy link

👍

@pjeannet
Copy link

pjeannet commented Feb 8, 2016

It is not working for RC1, cannot find EnumHelper.

@erasethis
Copy link

Same here, "EnumHelper doesn't exist in current context."

@dougbu
Copy link
Member

dougbu commented Feb 9, 2016

EnumHelper exists only in MVC 5. However Html.GetEnumSelectList() and its overloads could be used in place of EnumHelper.GetSelectList() in the code above. Please let us know if that approach is insufficient.

@pjeannet
Copy link

I tried to replace EnumHelper.GetSelectList(ViewData.ModelMetadata, (Enum)Model) by Html.GetEnumSelectList(Model.GetType()) and removed the condition EnumHelper.IsValidForEnumHelper(ViewData.ModelMetadata)) (didn't find equivalent in mvc6) and it compiles. However displayName = item.Text ?? item.Value never gets hit as itemis never in the state Selected. I don't know if I missed something?

@dougbu
Copy link
Member

dougbu commented Feb 10, 2016

Sorry, I glazed over your item.Selected use. That worked with EnumHelper because it had the model. But the code to determine Selected values duplicated what @Html.DropDownList() would do soon after in the normal case. We separated the concerns in ASP.NET Core MVC and GetEnumSelectList() doesn't have an overload accepting the model.

For this case, you likely need to @inject the IHtmlGenerator into your view and use GetCurrentValues() to get all of the strings that match the current model value. Then you'd need a more complicated comparison to determine which SelectListItem(s) was selected e.g. (from DefaultHtmlGenerator):

    var value = item.Value ?? item.Text;
    var selected = currentValues.Contains(value);

@pjeannet
Copy link

Ok, I got it working now 😄

I used the following code :

@model Enum
@inject Microsoft.AspNet.Mvc.ViewFeatures.IHtmlGenerator htmlGenerator

@{
    // Display Enum using same names(from [Display] attributes) as in editors
    string displayName = null;
    var currentValues = htmlGenerator.GetCurrentValues(ViewContext, ViewData.ModelExplorer, Model.GetType().Name, false);
    foreach (SelectListItem item in Html.GetEnumSelectList(Model.GetType()))
    {
        if (currentValues.Contains(item.Value))
        {
            displayName = item.Text ?? item.Value;
        }
    }

    // Handle the unexpected case that nothing is selected
    if (String.IsNullOrEmpty(displayName))
    {
        if (Model == null)
        {
            displayName = String.Empty;
        }
        else
        {
            displayName = Model.ToString();
        }
    }
    @Html.DisplayTextFor(model => displayName)

}```

@Drazzull
Copy link

Drazzull commented Jun 7, 2016

Thank you Pierre,

I have lost many hours to find your answer.

Microsoft could put this option by default in Html.DisplayFor().

@danroth27
Copy link
Member

@Eilon Is this really an enhancement? Is this just a bug that should be fixed?

@Eilon Eilon modified the milestones: 1.1.0, Backlog Aug 19, 2016
@ryanbrandenburg
Copy link
Contributor

@weitzhandler this should be fixed in 830983a. Thanks for the report!

@fschmied
Copy link

@ryanbrandenburg Will this also be added to ASP.NET MVC non-core? What is the policy regarding fixes and features in ASP.NET MVC 5? Is it documented somewhere?

@Eilon
Copy link
Member

Eilon commented Sep 23, 2016

@fschmied we don't generally back-port issues. Will this be an issue for you in ASP.NET MVC 5?

@fschmied
Copy link

@Eilon We can use the workaround (a dedicated display template for Enum) in MVC 5; I just wondered what the policy for backporting was - does MVC 5 still get features and/or fixes for bugs reported here on GitHub? Is the policy documented somewhere?

@Eilon
Copy link
Member

Eilon commented Sep 26, 2016

@fschmied we are still working on MVC 5.x, but usually only to fix high-priority bugs and ensuring that it all still works. By far most of our efforts are on ASP.NET Core.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests