0

Is there a better way of using Value and Text properties of SelectList than what I'm doing in my following View? I feel like I'm doing some extra work than it should be.

Note: I'm aware of other ways of using dropdowns with Value and Text. This question is only related to on how to achieve the same while using SelectList

...
var customersList = _context.Customers.Select(c => new SelectListItem { Value = c.LastName, Text = c.FullName });

MyViewModel.lstCustomers = new SelectList(customersList , "Value", "Text");
...
return View(MyViewModel);

I found similar methods here and here.

user2771704
  • 5,994
  • 6
  • 37
  • 38
nam
  • 21,967
  • 37
  • 158
  • 332
  • 1
    `customersList` is already `IEnumerable`. Using `new SelectList(...)` to create another identical `IEnumerable` is just pointless extra overhead. Your `lstCustomers` property should be `IEnumerable` since that is all that is required by the `DropDownListFor()` method in your view. –  Aug 15 '17 at 00:38
  • @StephenMuecke That's what I was worried about - doing unnecessary extra work. If I were to use `SelectList`, how should I use `Value` and `Text` attributes? – nam Aug 15 '17 at 02:14
  • Did you not understand my comment? Its the use of new `SelectList()` which is pointless. To generate a ` –  Aug 15 '17 at 02:17
  • And you cannot use `new SelectList(...)` for a collection of complex objects unless you don't specify the 2nd and 3rd parameters - it would just generate all `` because if you omit the 2nd and 3rd parameters it uses the `.ToString()` of the objects in the collection to generate the options display text –  Aug 15 '17 at 02:20
  • You either do `MyViewModel.lstCustomers = _context.Customers.Select(c => new SelectListItem { Value = c.LastName, Text = c.FullName });` or you do `MyViewModel.lstCustomers = new SelectList(_context.Customers, "LastName", "FullName");` not both –  Aug 15 '17 at 02:27
  • @StephenMuecke Your previous comment answered what I was looking for. That should be a response instead of a comment. – nam Aug 15 '17 at 02:30

1 Answers1

1

The HtmlHelper methods for generating a <select> element (@Html.DropDownListFor() etc) expect an IEnumerable<SelectListItem> as one of the parameters, therefore your lstCustomers should also be IEnumerable<SelectListItem>

public IEnumerable<SelectListItem> lstCustomers { get; set; }

You first line of code

var customersList = _context.Customers.Select(c => new SelectListItem { Value = c.LastName, Text = c.FullName });

is already generating that, so all that is required is

MyViewModel.lstCustomers = customersList;

You use of new SelectList(customersList , "Value", "Text"); is just creating another identical IEnumerable<SelectListItem> from the first one and is unnecessary extra overhead. (SelectList is IEnumerable<SelectListItem> and is just a wrapper around it to provide constructors to generate the collection).

If you want to use SelectList constructor then change your code to

var customersList = _context.Customers;
MyViewModel.lstCustomers = new SelectList(customersList , "LastName", "FullName");

Both will generate the same output. The difference between the methods is that the SelectList constructor uses reflection to determine which properties to use for the options value and display text, so is fractionally slower, and it uses 'magic strings' so is not strongly typed. The benefit is that its a little less verbose.

  • I've decided to use your last example; though fractionally slower - I like it's being less verbose. Thanks for details as, like myself, it should benefit other readers, as well. – nam Aug 15 '17 at 03:02
  • Yes, it really comes down to personal preference –  Aug 15 '17 at 03:09