c# - 从通用数据类型填充 SelectListItem
问题描述
我有以下代码,它从包含 Id 字段和 Name 字段的数据库表返回结果,并将其传输到 SelectListItems 列表(这会在我的视图中填充一个下拉框。)
var locationTypes = await APIHelper.GetAsync<List<LocationType>>(url);
var items = new List<SelectListItem>();
items.AddRange(locationTypes.Select(locationType =>
{
var item = new SelectListItem();
item.Value = locationType.LocationTypeId.ToString();
item.Text = locationType.Name;
return item;
}));
我在整个应用程序中重复了很多,用 LocationType 代替了其他各种东西。item.Value 始终获取返回数据的 Id 属性(Id 字段的格式始终为 {TableName}+“Id”),item.Text 始终获取“.Name”属性。
我怎样才能使这个通用?我正在尝试实现这样的目标,尽管它在语法上不正确并且可能是不正确的方法:
var myGenericObjects = await APIHelper.GetAsync<List<T>>(url)
var items = new List<SelectListItem>();
items.AddRange(myGenericObjects .Select(myGenericObjects =>
{
var item = new SelectListItem();
item.Value = myGenericObject.Field[0].ToString();
item.Text = myGenericObject.Name;
return item;
}));
解决方案
您可以为通用列表对象创建自定义扩展,然后使用反射检索您想要映射到 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; }
}
推荐阅读
- spring-data-jpa - 在 Spring 中持久化到多个数据库
- javascript - 使用拦截器和transformResponse时在axios中处理401
- python - Python 正则表达式:OR 语句在正则表达式模块中不起作用
- spring-kafka - spring-kafka-test 来自主题的轮询记录
- hibernate - Spring Boot - 持久化一个 @onetomany 实体
- java - 将 maven 应用程序打包到一个 jar 中 - 有一个例外
- javascript - 基本的 JavaScript 按钮交互
- java - 提供者 org.eclipse.jetty.apache.jsp.JuliLog 不是子类型
- php - 如何创建一个将返回数组或单个项目的类?
- amazon-web-services - AWS IAM - 如何提供对账单的访问权限?