Вы можете создать собственное расширение для универсального объекта списка, а затем с помощью отражения получить значения, которые вы хотите отобразить, в поля SelectListItem.Text и Name. Примечание. Я использую «nameof», чтобы избежать путаницы или магических строковых представлений свойств, которые я пытаюсь отобразить.
Я определил значение по умолчанию «Имя» для параметра namePropertyName. По вашему описанию это звучало так, как обычно, в большинстве ваших DTO есть свойство «Имя». Если это не так, просто удалите значение по умолчанию, которое определено.
Существуют дополнительные проверки, которые могут быть выполнены для этого расширения, чтобы предотвратить исключения NullReference и ArgumentExceptions, но для простоты примера были опущены. Пример. Обеспечение значения в параметрах idPropertyName и namePropertyName и обеспечение наличия этих имен свойств в предоставленном универсальном объекте до преобразования.
public static class ListExtensions
{
public static List<SelectListItem> ToSelectList<T>(this List<T> list, string idPropertyName, string namePropertyName = "Name")
where T : class, new()
{
List<SelectListItem> selectListItems = new List<SelectListItem>();
list.ForEach(item =>
{
selectListItems.Add(new SelectListItem
{
Text = item.GetType().GetProperty(namePropertyName).GetValue(item).ToString(),
Value = item.GetType().GetProperty(idPropertyName).GetValue(item).ToString()
});
});
return selectListItems;
}
}
Пример использования:
var testList = new List<TestDto>
{
new TestDto { Name = "Test0", TestId = 0 },
new TestDto { Name = "Test1", TestId = 1 },
new TestDto { Name = "Test2", TestId = 2 },
new TestDto { Name = "Test3", TestId = 3 },
new TestDto { Name = "Test4", TestId = 4 },
};
var selectList = testList.ToSelectList(nameof(TestDto.TestId), nameof(TestDto.Name));
Вот класс TestDto для справки:
public class TestDto
{
public int TestId { get; set; }
public string Name { get; set; }
}