asp.net - आप एएसपी.नेट एमवीसी में एनम से ड्रॉपडाउनलिस्ट कैसे बनाते हैं?




asp.net-mvc (20)

एमवीसी v5.1 के लिए Html.EnumDropDownListFor का उपयोग करें

@Html.EnumDropDownListFor(
    x => x.YourEnumField,
    "Select My Type", 
    new { @class = "form-control" })

एमवीसी v5 के लिए EnumHelper का उपयोग करें

@Html.DropDownList("MyType", 
   EnumHelper.GetSelectList(typeof(MyType)) , 
   "Select My Type", 
   new { @class = "form-control" })

एमवीसी 5 और उससे कम के लिए

मैंने रूने के जवाब को विस्तार विधि में घुमाया:

namespace MyApp.Common
{
    public static class MyExtensions{
        public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
            where TEnum : struct, IComparable, IFormattable, IConvertible
        {
            var values = from TEnum e in Enum.GetValues(typeof(TEnum))
                select new { Id = e, Name = e.ToString() };
            return new SelectList(values, "Id", "Name", enumObj);
        }
    }
}

यह आपको लिखने की अनुमति देता है:

ViewData["taskStatus"] = task.Status.ToSelectList();

using MyApp.Common

मैं Html.DropDownList एक्सटेंशन विधि का उपयोग करने का प्रयास कर रहा हूं लेकिन यह समझ नहीं सकता कि इसे गणना के साथ कैसे उपयोग किया जाए।

मान लें कि मेरे पास इस तरह की गणना है:

public enum ItemTypes
{
    Movie = 1,
    Game = 2,
    Book = 3
}

मैं Html.DropDownList एक्सटेंशन विधि का उपयोग करके इन मानों के साथ एक ड्रॉपडाउन बनाने के बारे में कैसे जा सकता हूं?

या बस लूप बनाने और मैन्युअल रूप से एचटीएमएल तत्व बनाने के लिए मेरी सबसे अच्छी शर्त है?


Html.DropDownListFor केवल एक आईनेमरेबल की आवश्यकता है, इसलिए पुरस्कार के समाधान का विकल्प निम्नानुसार है। यह आपको बस लिखने की अनुमति देगा:

@Html.DropDownListFor(m => m.SelectedItemType, Model.SelectedItemType.ToSelectList())

[जहां SelectedItemType आपके मॉडल प्रकार टाइपटाइप पर एक फ़ील्ड है, और आपका मॉडल गैर-शून्य है]

साथ ही, आपको एक्सटेंशन विधि को सामान्य रूप से जेनरेट करने की आवश्यकता नहीं है क्योंकि आप टाइपऑफ (टी) के बजाय enumValue.GetType () का उपयोग कर सकते हैं।

संपादित करें: यहां समेकित साइमन का समाधान भी शामिल है, और इसमें ToDescription एक्सटेंशन विधि शामिल है।

public static class EnumExtensions
{
    public static IEnumerable<SelectListItem> ToSelectList(this Enum enumValue)
    {
        return from Enum e in Enum.GetValues(enumValue.GetType())
               select new SelectListItem
               {
                   Selected = e.Equals(enumValue),
                   Text = e.ToDescription(),
                   Value = e.ToString()
               };
    }

    public static string ToDescription(this Enum value)
    {
        var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
        return attributes.Length > 0 ? attributes[0].Description : value.ToString();
    }
}

आप Enum.GetValues जैसे कुछ का उपयोग करना चाहते हैं


इस विस्तार विधि के लिए एक और फिक्स - वर्तमान संस्करण enum के वर्तमान मूल्य का चयन नहीं किया था। मैंने अंतिम पंक्ति तय की:

public static SelectList ToSelectList<TEnum>(this TEnum enumObj) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

        var values = from TEnum e in Enum.GetValues(typeof(TEnum))
                       select new
                       {
                           ID = (int)Enum.Parse(typeof(TEnum), e.ToString()),
                           Name = e.ToString()
                       };


        return new SelectList(values, "ID", "Name", ((int)Enum.Parse(typeof(TEnum), enumObj.ToString())).ToString());
    }

ऐसा करने का एक आसान आसान तरीका - बिना विस्तारित सभी एक्सटेंशन सामानों के यह है:

आपका enum:

    public enum SelectedLevel
    {
       Level1,
       Level2,
       Level3,
       Level4
    }

अपने नियंत्रक के अंदर एनम को एक सूची में बांधें:

    List<SelectedLevel> myLevels = Enum.GetValues(typeof(SelectedLevel)).Cast<SelectedLevel>().ToList();

उसके बाद इसे एक व्यूबैग में फेंक दें:

    ViewBag.RequiredLevel = new SelectList(myLevels);

आखिरकार इसे देखने के लिए बाध्य करें:

    @Html.DropDownList("selectedLevel", (SelectList)ViewBag.RequiredLevel, new { @class = "form-control" })

यह अब तक का सबसे आसान तरीका है और मुझे किसी भी एक्सटेंशन या पागल की आवश्यकता नहीं है।

अद्यतन : नीचे एंड्रयूज टिप्पणी देखें।


खैर, मैं पार्टी के लिए वास्तव में देर से हूं, लेकिन इसके लायक होने के लिए, मैंने इस विषय के बारे में ब्लॉग किया है जिससे मैं एक EnumHelper क्लास बनाता EnumHelper जो बहुत आसान परिवर्तन को सक्षम बनाता है।

http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23

आपके नियंत्रक में:

//If you don't have an enum value use the type
ViewBag.DropDownList = EnumHelper.SelectListFor<MyEnum>();

//If you do have an enum value use the value (the value will be marked as selected)    
ViewBag.DropDownList = EnumHelper.SelectListFor(MyEnum.MyEnumValue);

आपके दृश्य में:

@Html.DropDownList("DropDownList")
@* OR *@
@Html.DropDownListFor(m => m.Property, ViewBag.DropDownList as SelectList, null)

सहायक वर्ग:

public static class EnumHelper
{
    // Get the value of the description attribute if the   
    // enum has one, otherwise use the value.  
    public static string GetDescription<TEnum>(this TEnum value)
    {
        var fi = value.GetType().GetField(value.ToString());

        if (fi != null)
        {
            var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attributes.Length > 0)
            {
                return attributes[0].Description;
            }
        }

        return value.ToString();
    }

    /// <summary>
    /// Build a select list for an enum
    /// </summary>
    public static SelectList SelectListFor<T>() where T : struct
    {
        Type t = typeof(T);
        return !t.IsEnum ? null
                         : new SelectList(BuildSelectListItems(t), "Value", "Text");
    }

    /// <summary>
    /// Build a select list for an enum with a particular value selected 
    /// </summary>
    public static SelectList SelectListFor<T>(T selected) where T : struct
    {
        Type t = typeof(T);
        return !t.IsEnum ? null
                         : new SelectList(BuildSelectListItems(t), "Text", "Value", selected.ToString());
    }

    private static IEnumerable<SelectListItem> BuildSelectListItems(Type t)
    {
        return Enum.GetValues(t)
                   .Cast<Enum>()
                   .Select(e => new SelectListItem { Value = e.ToString(), Text = e.GetDescription() });
    }
}

पुरस्कार और रूने के उत्तरों पर विस्तार करना, यदि आप अपनी चुनिंदा सूची वस्तुओं की मान विशेषता चाहते हैं तो स्ट्रिंग मान की बजाय गणना प्रकार के पूर्णांक मान पर नक्शा लगाएं, निम्न कोड का उपयोग करें:

public static SelectList ToSelectList<T, TU>(T enumObj) 
    where T : struct
    where TU : struct
{
    if(!typeof(T).IsEnum) throw new ArgumentException("Enum is required.", "enumObj");

    var values = from T e in Enum.GetValues(typeof(T))
                 select new { 
                    Value = (TU)Convert.ChangeType(e, typeof(TU)),
                    Text = e.ToString() 
                 };

    return new SelectList(values, "Value", "Text", enumObj);
}

प्रत्येक गणना मूल्य को टीनम ऑब्जेक्ट के रूप में पेश करने के बजाय, हम इसे ऑब्जेक्ट के रूप में देख सकते हैं और फिर इसे अनबॉक्स किए गए मान प्राप्त करने के लिए पूर्णांक में डाल सकते हैं।

नोट: मैंने उन प्रकारों को प्रतिबंधित करने के लिए एक सामान्य प्रकार की बाधा भी शामिल की है जिसके लिए यह एक्सटेंशन केवल structs (Enum का बेस टाइप), और रन-टाइम प्रकार सत्यापन के लिए उपलब्ध है जो सुनिश्चित करता है कि पारित संरचना वास्तव में एक enum है।

अद्यतन 10/23/12: .NET 4+ को प्रभावित करने वाले अंतर्निहित प्रकार और निश्चित गैर-संकलन समस्या के लिए सामान्य प्रकार पैरामीटर जोड़ा गया।


पुरस्कार की विस्तार विधि का उपयोग करके टेक्स्ट की बजाय संख्या प्राप्त करने की समस्या को हल करने के लिए।

public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
{
  var values = from TEnum e in Enum.GetValues(typeof(TEnum))
               select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString())
                         , Name = e.ToString() };

  return new SelectList(values, "Id", "Name", enumObj);
}

मुझे पता है कि इस पर पार्टी के लिए देर हो चुकी है, लेकिन सोचा कि आपको यह संस्करण उपयोगी हो सकता है, क्योंकि यह आपको ड्रॉप डाउन में गणना स्थिरांक की बजाय वर्णनात्मक तारों का उपयोग करने की अनुमति देता है। ऐसा करने के लिए, एक [System.ComponentModel.Description] विशेषता के साथ प्रत्येक गणना प्रविष्टि को सजाने के लिए।

उदाहरण के लिए:

public enum TestEnum
{
  [Description("Full test")]
  FullTest,

  [Description("Incomplete or partial test")]
  PartialTest,

  [Description("No test performed")]
  None
}

मेरा कोड यहाँ है:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Reflection;
using System.ComponentModel;
using System.Linq.Expressions;

 ...

 private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
    {
        Type realModelType = modelMetadata.ModelType;

        Type underlyingType = Nullable.GetUnderlyingType(realModelType);
        if (underlyingType != null)
        {
            realModelType = underlyingType;
        }
        return realModelType;
    }

    private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } };

    public static string GetEnumDescription<TEnum>(TEnum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());

        DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

        if ((attributes != null) && (attributes.Length > 0))
            return attributes[0].Description;
        else
            return value.ToString();
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
    {
        return EnumDropDownListFor(htmlHelper, expression, null);
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        Type enumType = GetNonNullableModelType(metadata);
        IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();

        IEnumerable<SelectListItem> items = from value in values
            select new SelectListItem
            {
                Text = GetEnumDescription(value),
                Value = value.ToString(),
                Selected = value.Equals(metadata.Model)
            };

        // If the enum is nullable, add an 'empty' item to the collection
        if (metadata.IsNullableValueType)
            items = SingleEmptyItem.Concat(items);

        return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
    }

फिर आप इसे अपने विचार में कर सकते हैं:

@Html.EnumDropDownListFor(model => model.MyEnumProperty)

उम्मीद है कि यह आपकी मदद करता है!

संपादित करें 2014-जनवरी -23: माइक्रोसॉफ्ट ने अभी एमवीसी 5.1 जारी किया है, जिसमें अब एनमड्रॉपडाउनलिस्ट फीचर है। अफसोस की बात यह है कि यह [विवरण] विशेषता का सम्मान नहीं करता है, इसलिए उपर्युक्त कोड अभी भी खड़ा है। ( माइक्रोसॉफ्ट के रिलीज नोट्स के लिए http://www.asp.net/mvc/overview/releases/mvc51-release-notes#Enum देखें ।)

अद्यतन: यह Display विशेषता [Display(Name = "Sample")] समर्थन करता है, हालांकि कोई इसका उपयोग कर सकता है।

[अपडेट - बस यह देखा, और कोड कोड के विस्तारित संस्करण की तरह दिखता है: http://blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums.aspx , कुछ जोड़ों के साथ। यदि ऐसा है, तो एट्रिब्यूशन निष्पक्ष प्रतीत होगा ;-)]


मैं एक ही समस्या में फंस गया, इस सवाल को पाया, और सोचा कि ऐश द्वारा प्रदान किया गया समाधान वह नहीं था जिसे मैं ढूंढ रहा था; HTML बनाने के लिए स्वयं अंतर्निहित Html.DropDownList() फ़ंक्शन की तुलना में कम लचीलापन का मतलब है।

सी # 3 चालू करता है यह बहुत आसान बनाता है। मेरे पास TaskStatus नामक एक enum :

var statuses = from TaskStatus s in Enum.GetValues(typeof(TaskStatus))
               select new { ID = s, Name = s.ToString() };
ViewData["taskStatus"] = new SelectList(statuses, "ID", "Name", task.Status);

यह एक अच्छा ओल ' SelectList बनाता है जिसका उपयोग आपके द्वारा दृश्य में उपयोग किए जाने के लिए किया जा सकता है:

<td><b>Status:</b></td><td><%=Html.DropDownList("taskStatus")%></td></tr>

गुमनाम प्रकार और LINQ यह इतना अधिक सुरुचिपूर्ण IMHO बनाता है। कोई अपराध इरादा नहीं, एश। :)


यह रेजर के लिए संस्करण है:

@{
    var itemTypesList = new List<SelectListItem>();
    itemTypesList.AddRange(Enum.GetValues(typeof(ItemTypes)).Cast<ItemTypes>().Select(
                (item, index) => new SelectListItem
                {
                    Text = item.ToString(),
                    Value = (index).ToString(),
                    Selected = Model.ItemTypeId == index
                }).ToList());
 }


@Html.DropDownList("ItemTypeId", itemTypesList)

यहां एक बेहतर encapsulated समाधान है:

http://www.spicelogic.com/Journal/ASP-NET-MVC-DropDownListFor-Html-Helper-Enum-5

कहो आपका मॉडल है:

नमूना उपयोग:

जेनरेटेड यूआई:

और उत्पन्न एचटीएमएल

सहायक विस्तार स्रोत कोड स्नैप शॉट:

आप दिए गए लिंक से नमूना प्रोजेक्ट डाउनलोड कर सकते हैं।

संपादित करें: यहां कोड है:

public static class EnumEditorHtmlHelper
{
    /// <summary>
    /// Creates the DropDown List (HTML Select Element) from LINQ 
    /// Expression where the expression returns an Enum type.
    /// </summary>
    /// <typeparam name="TModel">The type of the model.</typeparam>
    /// <typeparam name="TProperty">The type of the property.</typeparam>
    /// <param name="htmlHelper">The HTML helper.</param>
    /// <param name="expression">The expression.</param>
    /// <returns></returns>
    public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression) 
        where TModel : class
    {
        TProperty value = htmlHelper.ViewData.Model == null 
            ? default(TProperty) 
            : expression.Compile()(htmlHelper.ViewData.Model);
        string selected = value == null ? String.Empty : value.ToString();
        return htmlHelper.DropDownListFor(expression, createSelectList(expression.ReturnType, selected));
    }

    /// <summary>
    /// Creates the select list.
    /// </summary>
    /// <param name="enumType">Type of the enum.</param>
    /// <param name="selectedItem">The selected item.</param>
    /// <returns></returns>
    private static IEnumerable<SelectListItem> createSelectList(Type enumType, string selectedItem)
    {
        return (from object item in Enum.GetValues(enumType)
                let fi = enumType.GetField(item.ToString())
                let attribute = fi.GetCustomAttributes(typeof (DescriptionAttribute), true).FirstOrDefault()
                let title = attribute == null ? item.ToString() : ((DescriptionAttribute) attribute).Description
                select new SelectListItem
                  {
                      Value = item.ToString(), 
                      Text = title, 
                      Selected = selectedItem == item.ToString()
                  }).ToList();
    }
}

http://www.asp.net/mvc/overview/releases/mvc51-release-notes#Enum , उन्होंने EnumDropDownListFor() सहायक जोड़ा, इसलिए कस्टम एक्सटेंशन की आवश्यकता नहीं है:

आदर्श :

public enum MyEnum
{
    [Display(Name = "First Value - desc..")]
    FirstValue,
    [Display(Name = "Second Value - desc...")]
    SecondValue
}

देखें :

@Html.EnumDropDownListFor(model => model.MyEnum)

टैग हेल्पर (एएसपी.नेट एमवीसी 6) का उपयोग करना :

<select asp-for="@Model.SelectedValue" asp-items="Html.GetEnumSelectList<MyEnum>()">

@Simon Goldstone: Thanks for your solution, it can be perfectly applied in my case. The only problem is I had to translate it to VB. But now it is done and to save other people's time (in case they need it) I put it here:

Imports System.Runtime.CompilerServices
Imports System.ComponentModel
Imports System.Linq.Expressions

Public Module HtmlHelpers
    Private Function GetNonNullableModelType(modelMetadata As ModelMetadata) As Type
        Dim realModelType = modelMetadata.ModelType

        Dim underlyingType = Nullable.GetUnderlyingType(realModelType)

        If Not underlyingType Is Nothing Then
            realModelType = underlyingType
        End If

        Return realModelType
    End Function

    Private ReadOnly SingleEmptyItem() As SelectListItem = {New SelectListItem() With {.Text = "", .Value = ""}}

    Private Function GetEnumDescription(Of TEnum)(value As TEnum) As String
        Dim fi = value.GetType().GetField(value.ToString())

        Dim attributes = DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())

        If Not attributes Is Nothing AndAlso attributes.Length > 0 Then
            Return attributes(0).Description
        Else
            Return value.ToString()
        End If
    End Function

    <Extension()>
    Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TEnum))) As MvcHtmlString
        Return EnumDropDownListFor(htmlHelper, expression, Nothing)
    End Function

    <Extension()>
    Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TEnum)), htmlAttributes As Object) As MvcHtmlString
        Dim metaData As ModelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData)
        Dim enumType As Type = GetNonNullableModelType(metaData)
        Dim values As IEnumerable(Of TEnum) = [Enum].GetValues(enumType).Cast(Of TEnum)()

        Dim items As IEnumerable(Of SelectListItem) = From value In values
            Select New SelectListItem With
            {
                .Text = GetEnumDescription(value),
                .Value = value.ToString(),
                .Selected = value.Equals(metaData.Model)
            }

        ' If the enum is nullable, add an 'empty' item to the collection
        If metaData.IsNullableValueType Then
            items = SingleEmptyItem.Concat(items)
        End If

        Return htmlHelper.DropDownListFor(expression, items, htmlAttributes)
    End Function
End Module

End You use it like this:

@Html.EnumDropDownListFor(Function(model) (model.EnumField))

I ended up creating extention methods to do what is essentially the accept answer here. The last half of the Gist deals with Enum specifically.

https://gist.github.com/3813767


I found an answer here http://blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums.aspx ; however, some of my enums have [Description(...)] attribute, so I've modified the code to provide support for that:

    enum Abc
    {
        [Description("Cba")]
        Abc,

        Def
    }


    public static MvcHtmlString EnumDropDownList<TEnum>(this HtmlHelper htmlHelper, string name, TEnum selectedValue)
    {
        IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum))
            .Cast<TEnum>();

        List<SelectListItem> items = new List<SelectListItem>();
        foreach (var value in values)
        {
            string text = value.ToString();

            var member = typeof(TEnum).GetMember(value.ToString());
            if (member.Count() > 0)
            {
                var customAttributes = member[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (customAttributes.Count() > 0)
                {
                    text = ((DescriptionAttribute)customAttributes[0]).Description;
                }
            }

            items.Add(new SelectListItem
            {
                Text = text,
                Value = value.ToString(),
                Selected = (value.Equals(selectedValue))
            });
        }

        return htmlHelper.DropDownList(
            name,
            items
            );
    }

उम्मीद है की वो मदद करदे।


This is my version of helper method. मैं इसका उपयोग करता हूं:

var values = from int e in Enum.GetValues(typeof(TEnum))
             select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };

Instead of that:

var values = from TEnum e in Enum.GetValues(typeof(TEnum))
           select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString())
                     , Name = e.ToString() };

यह रहा:

public static SelectList ToSelectList<TEnum>(this TEnum self) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum)
        {
            throw new ArgumentException("self must be enum", "self");
        }

        Type t = typeof(TEnum);

        var values = from int e in Enum.GetValues(typeof(TEnum))
                     select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };

        return new SelectList(values, "ID", "Name", self);
    }

You can also use my custom HtmlHelpers in Griffin.MvcContrib. The following code:

@Html2.CheckBoxesFor(model => model.InputType) <br />
@Html2.RadioButtonsFor(model => model.InputType) <br />
@Html2.DropdownFor(model => model.InputType) <br />

Generates:

https://github.com/jgauffin/griffin.mvccontrib


@Html.DropDownListFor(model => model.MaritalStatus, new List<SelectListItem> 
{  

new SelectListItem { Text = "----Select----", Value = "-1" },


new SelectListItem { Text = "Marrid", Value = "M" },


 new SelectListItem { Text = "Single", Value = "S" }

})

@Html.DropDownListFor(model => model.Type, Enum.GetNames(typeof(Rewards.Models.PropertyType)).Select(e => new SelectListItem { Text = e }))




asp.net-mvc