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.
To solve the problem Temporarily。add a shared view of enum。
just like this:
``` c#
@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)
}
```
:+1:
It is not working for RC1, cannot find EnumHelper.
Same here, "EnumHelper doesn't exist in current context."
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.
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?
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):
c#
var value = item.Value ?? item.Text;
var selected = currentValues.Contains(value);
Ok, I got it working now :smile:
I used the following code :
`````` c#
@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)
}```
``````
Thank you Pierre,
I have lost many hours to find your answer.
Microsoft could put this option by default in Html.DisplayFor().
@Eilon Is this really an enhancement? Is this just a bug that should be fixed?
@weitzhandler this should be fixed in 830983a. Thanks for the report!
@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?
@fschmied we don't generally back-port issues. Will this be an issue for you in ASP.NET MVC 5?
@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?
@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.
Most helpful comment
Ok, I got it working now :smile:
I used the following code :
`````` c#
@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;
}
}
}```
``````