-1

This is my view model class:

public class CustomerEditViewModel
{
    [Display(Name = "Customer Number")] 
    public string CustomerID { get; set; }

    [Display(Name = "Customer Name")] 
    public string CustomerName { get; set; }

    [Display(Name = "Customer Country")] 
    public string Country { get; set; }
}

I need to populate a dropdown with properties of this class, so the property name will be the value and Display.Name will be text of the dropdown item.

The <select> HTML would look like this:

<select>
  <option value="">--Select--</option>
  <option value="CustomerID">Customer Number</option>
  <option value="CustomerName">Customer Name</option>
  <option value="Country">Customer Country</option>
</select>

EDIT

Based on Taylor wood answer. i created a small sample code. here it is.

Model code

public class MySkills
{
    public IEnumerable<SelectListItem> Skills
    {
        get;
        set;
    }  
}  

public class CustomerEditViewModel
{
    [Display(Name = "Customer Number")]
    public string CustomerID { get; set; }

    [Display(Name = "Customer Name")]
    public string CustomerName { get; set; }

    [Display(Name = "Customer Country")]
    public string Country { get; set; }
}

Controller & action code

public class HomeController : Controller
    {

         public ActionResult Index()
        {
            var items = from p in typeof(CustomerEditViewModel).GetProperties()
                        let name = p.GetCustomAttribute<DisplayAttribute>().Name
                        select new SelectListItem() { Text = name, Value = p.Name };

            var ClassData = new MySkills();

            var selectList = new List<SelectListItem>();
            foreach (var item in items)
            {
                selectList.Add(new SelectListItem
                {
                    Value = item.Value.ToString(),
                    Text = item.Text
                });
            }
            ClassData.Skills = selectList;

            return View(ClassData);
        }
}

View

@model WebTestDropDown.Controllers.MySkills
@{
    ViewBag.Title = "Home Page";
}
<br /><br /><br /><br />
<tr>
    <td> Populating With Model Data </td>
    <td> @Html.DropDownList("ClassData", Model.Skills) </td>
</tr>  
Monojit Sarkar
  • 2,353
  • 8
  • 43
  • 94
  • Hi, I have a concern, why do you want it in this way? Honestly, it seems a bit confusing from the class to the options. What would I do? Reflection, https://stackify.com/what-is-c-reflection/ with this you can manipulate and then populate your DropDown. – Federico Navarrete Feb 09 '18 at 13:02
  • 1
    You would need to write your own `HtmlHelper` method to do that, or build a `IEnumerable` based on the properties and the values of the annotations to use in the `DropDownListFor()` method –  Feb 09 '18 at 13:02
  • @StephenMuecke what you try to say not clear. can you provide bit code sample for hint to do it. – Monojit Sarkar Feb 09 '18 at 13:04
  • You can use reflection to read each property of the class and their attributes. But this really makes no sense and its hard to understand why you would want to do this. –  Feb 09 '18 at 13:06
  • @FedericoNavarrete well, you might use this for search in fields selection. Put something in search box, and select where you want to look for that value in the database. – hazimdikenli Feb 09 '18 at 13:13
  • 1
    Like I've told you on your past few questions: don't [ask a new question for every hurdle you encounter while trying to do something](https://stackoverflow.com/users/6188148/monojit-sarkar?tab=questions), but **read [ask] and research it first**. Al you're dumping is _"how do you do this"_ questions, without showing what you have tried. Create a POC, try something on your own first. – CodeCaster Feb 09 '18 at 13:31

2 Answers2

2

You can use reflection to get the property names and their respective Display.Name attribute values:

var modelType = typeof(CustomerEditViewModel);
var properties = modelType.GetProperties();
foreach (var property in properties) {
  var displayAttr = property.GetCustomAttribute<DisplayAttribute>();
  Console.WriteLine(string.Format("{0}->{1}", property.Name, displayAttr.Name));
}

Prints the following:

CustomerID->Customer Number
CustomerName->Customer Name
Country->Customer Country

Then build your select list items based on that. For example, using LINQ:

var items = from p in typeof(CustomerEditViewModel).GetProperties()
            let name = p.GetCustomAttribute<DisplayAttribute>().Name
            select new SelectListItem() {Text = p.Name, Value = name};
Taylor Wood
  • 15,886
  • 1
  • 20
  • 37
  • thanks for answer. how can i populate dropdown in razor with items like `@Html.DropDownListFor(x => x.SelectedName, x.Text)` ? – Monojit Sarkar Feb 09 '18 at 13:44
  • this code `p.GetCustomAttribute()` is not compiling. please tell me what to add as a namespace at to. i added `using System.ComponentModel.DataAnnotations; using System.Reflection; using System.ComponentModel;` tell me what else i need to do to run this code? – Monojit Sarkar Feb 09 '18 at 14:26
  • this way it is fixed now `p.GetCustomAttribute()` – Monojit Sarkar Feb 09 '18 at 14:31
0

based on @Taylor Wood answer

var modelType = typeof(CustomerEditViewModel);
var properties = modelType.GetProperties();
List<SelectListItme>yourList = new List<SelectListItme>();
foreach (var property in properties) {
  var displayAttr = property.GetCustomAttribute<Display>();
   yourList.Add(new 
   SelectListItem{Text=Property.Name,Value=displayAttr.Name,Selected=false}) 
}

and in View just display you selectlistitem

RAHUL S R
  • 1,569
  • 1
  • 11
  • 20
  • this code p.GetCustomAttribute() is not compiling. please tell me what to add as a namespace at to. i added using System.ComponentModel.DataAnnotations; using System.Reflection; using System.ComponentModel; tell me what else i need to do to run this code? – Monojit Sarkar Feb 09 '18 at 14:26
  • system.reflection is enough go through this msdn blog https://msdn.microsoft.com/en-us/library/system.attribute.getcustomattribute(v=vs.110).aspx – RAHUL S R Feb 09 '18 at 19:49