Reputation: 172
I currently have a working setup but I would like to know if there is a better implementation.
I have a Genre.cs enum in ~/Models/Genre.cs
Which is passed to the view in a view model:
public IActionResult Index()
{
MusicFileCreateViewModel musicFileCreateViewModel = new MusicFileCreateViewModel
{
Genres = Enum.GetNames(typeof(Genre)), // This is a string[]
// ...
};
return View(musicFileCreateViewModel);
}
Which is then handled in the view and used in the ~/js/musicFileList.js
file
@model MusicFileCreateViewModel
// ...
<script>
var Genres = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.Genres));
</script>
<script src="~/js/musicFileList.js"></script>
Is there a way to improve this setup? Also, is it possible to get the enum display names instead of the actual names?
Upvotes: 0
Views: 721
Reputation: 4022
To improve this setup
I agree with @Martin Staufcik, use a api to obtain enum data.
Creat new action
to get genres
[Route("/genres")]
public IList<string> GetGenres()
{
return EnumHelper<Genre>.GetDisplayValues(Genre.Rock);
}
add js
to request genres
<script type="text/javascript">
$.post("/genres", null, function (data, status) {
//data : ROCK, ELECTRONIC, SOUL, FUNK, COUNTRY
alert(data[1]);//ELECTRONIC
});
</script>
Is it possible to get the enum display names instead of the actual names?
(1) Import EnumHelper
to get Enum display names
EnumHelper.cs
public static class EnumHelper<T>
{
public static IList<T> GetValues(Enum value)
{
var enumValues = new List<T>();
foreach (FieldInfo fi in value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public))
{
enumValues.Add((T)Enum.Parse(value.GetType(), fi.Name, false));
}
return enumValues;
}
public static T Parse(string value)
{
return (T)Enum.Parse(typeof(T), value, true);
}
public static IList<string> GetNames(Enum value)
{
return value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public).Select(fi => fi.Name).ToList();
}
public static IList<string> GetDisplayValues(Enum value)
{
return GetNames(value).Select(obj => GetDisplayValue(Parse(obj))).ToList();
}
private static string lookupResource(Type resourceManagerProvider, string resourceKey)
{
foreach (PropertyInfo staticProperty in resourceManagerProvider.GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
{
if (staticProperty.PropertyType == typeof(System.Resources.ResourceManager))
{
System.Resources.ResourceManager resourceManager = (System.Resources.ResourceManager)staticProperty.GetValue(null, null);
return resourceManager.GetString(resourceKey);
}
}
return resourceKey; // Fallback with the key name
}
public static string GetDisplayValue(T value)
{
var fieldInfo = value.GetType().GetField(value.ToString());
var descriptionAttributes = fieldInfo.GetCustomAttributes(
typeof(DisplayAttribute), false) as DisplayAttribute[];
if (descriptionAttributes[0].ResourceType != null)
return lookupResource(descriptionAttributes[0].ResourceType, descriptionAttributes[0].Name);
if (descriptionAttributes == null) return string.Empty;
return (descriptionAttributes.Length > 0) ? descriptionAttributes[0].Name : value.ToString();
}
}
(2) Add Genres
to MusicFileCreateViewModel model
MusicFileCreateViewModel.cs
namespace EnumApplication.Models
{
public enum Genre
{
[Display(Name = "ROCK")]
Rock,
[Display(Name = "ELECTRONIC")]
Electronic,
[Display(Name = "SOUL")]
Soul,
[Display(Name = "FUNK")]
Funk,
[Display(Name = "COUNTRY")]
Country
}
public class MusicFileCreateViewModel
{
public int Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public IList<string> Genres { get; set; }
}
}
(3) Set Enum names to Genres
by using EnumHelper
Index action in controller
public IActionResult Index()
{
MusicFileCreateViewModel musicFileCreateViewModel = new MusicFileCreateViewModel
{
Genres = EnumHelper<Genre>.GetDisplayValues(Genre.Rock),// This is a string[]
// ...
};
return View(musicFileCreateViewModel);
}
(4) Json Serialize
Index.cshtml
<ul>
@foreach (var value in Model.Genres)
{
<li>@Html.DisplayName(value)</li>
}
</ul>
<script type="text/javascript">
function Fn() {
var Genres = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.Genres));
}
</script>
EnumHelper coded by @Hrvoje Stanisic
Upvotes: 1