Могу ли я настроить текстовое поле данных в MVC SelectList для использования с HtmlHelper.DropDownList без необходимости создания новой структуры или класса?

Я создаю SelectList из класса List (T), чтобы использовать для заполнения HtmlHelper.DropDownList в представлении MVC, устанавливая dataValueField и dataTextField в конструкторе Select List. Текст, который должен отображаться, не удовлетворяет одному из свойств моего класса и все еще нуждается в манипулировании. Есть ли способ сделать это с помощью конструктора SelectList? Я понимаю, что могу сделать это, создав структуру или класс для использования в качестве входа IEnumerable для списка Select, но я бы предпочел, если мне не нужно.

Код My Controller в настоящее время:

        var members = MemberService.GetAll();
        this.ViewData["Members"] = new SelectList(members, "Id", "Name");

В настоящее время мой код просмотра:

        <%= Html.DropDownList("Members") %>

Вместо "Фамилия" в качестве поля отображения я хотел бы иметь возможность предварительно форматировать поле, комбинируя (и форматируя) два свойства.

Ответ 1

Вы можете создать цикл через список участников, добавив значения в новый список, из которого вы затем создадите SelectList. Что-то вроде:

var members = MemberService.GetAll();
List<object> newList = new List<object>();
foreach(var member in members)
    newList.Add( new { 
        Id = member.Id, 
        Name = member.Name + " " + member.Surname 
    } );
this.ViewData["Members"] = new SelectList(newList, "Id", "Name");

Я не могу вспомнить, можете ли вы использовать анонимный тип или нет, но если вы не можете создать небольшой класс данных для использования в качестве посредника.

Ответ 2

Вы можете создать метод расширения и установить все, что хотите, в качестве текста. Это может быть что-то вроде

public static IList<SelectListItem> ToSelectList<T>(this IEnumerable<T> itemsToMap, Func<T, string> textProperty, Func<T, string> valueProperty, Predicate<T> isSelected)
{
    var result = new List<SelectListItem>();

    foreach (var item in itemsToMap)
    {
        result.Add(new SelectListItem
        {
            Value = valueProperty(item),
            Text = textProperty(item),
            Selected = isSelected(item)
        });
    }
    return result;
}

Затем вы вызываете этот метод как:

var membersSelectList = MemberService.GetAll().ToSelectList(m=>m.FirstName + " " + m.Surname, m.Id.ToString(), m=>m.Id < -1); //Any predicate you need here.

Ответ 3

Для тех, кто использует LINQ. Вместо:

    var members = MemberService.GetAll();

вы можете использовать:

    ViewBag.MembersList = new SelectList(
    from x in db.members where x.role = 5 select new {x.ID, x.Name, x.Surname, S_Name = x.Surname + " " + x.Name}, 
    "ID", "S_Name");

а затем используйте ViewBag.MemberList в вашем коде Razor, например

    @Html.DropDownList("MembersList", String.Empty)