0

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?

2
  • If you are not using frontend technologies, such as angular, this setup is ok. When using angular, you could create an API method that would prepare the data structures needed for the form. Commented Jul 7, 2020 at 19:28
  • Hi, @TyGuy96, I already post the code to solve your question. It works on me. If the answer solved your question, please mark it for helping more people. If not, we may be able to continue to explore solutions. Thank you for your time and efforts. Commented Jul 10, 2020 at 9:09

1 Answer 1

1

To improve this setup

I agree with @Martin Staufcik, use a api to obtain enum data.

  1. Creat new action to get genres

        [Route("/genres")]
        public IList<string> GetGenres()
        {
            return EnumHelper<Genre>.GetDisplayValues(Genre.Rock);
        }
    
  2. 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>
    

![![enter image description here

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>

Screenshots of Test: enter image description here

EnumHelper coded by @Hrvoje Stanisic

Sign up to request clarification or add additional context in comments.

2 Comments

In your $.post("/genres", null, function (data) function, I am getting "'data' does not exist in the current context" when being passed to the SerializeObject function. Any idea why?
Hi, sorry, my fault, No need to SerializeObject again, it's already serialized. I already update my codes and please try again. :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.