自动映射器映射 IEnumerable 用于下拉菜单
本文关键字:映射 用于 SelectListItem 下拉菜单 IEnumerable | 更新日期: 2023-09-27 18:36:27
>问题
我目前正在向我的 MVC 项目添加自动映射,但我被卡住了。现在我有一个用于表示数据库中数据的用户模型。我必须将该模型映射到 EditUserModel,该模型将在调用 Edit 方法时使用。EditUserModel 有IEnumerable<SelectListItem>
(用于下拉菜单),我似乎无法弄清楚如何映射。
尝试的解决方案
截至目前,我还没有尝试实施任何东西。我不确定IEnumerable<SelectListItem>
的最佳地点或居住地。现在,它正在控制器中填充。
用户.cs
public class User
{
[Key]
public int UserID { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public int RoleID { get; set; }
[ForeignKey("RoleID")]
public virtual Role Role { get; set; }
}
编辑用户模型.cs
public class EditUserViewModel
{
[HiddenInput(DisplayValue = false)]
public int UserID { get; set; }
[Required]
public String Username { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[DisplayName("Role")]
[Required]
public int RoleID { get; set; }
//The trouble field
public IEnumerable<SelectListItem> Roles { get; set; }
}
控制器.cs
EditUserViewModel model = new EditUserViewModel();
//Population of the dropdown menu
model.Roles = context.Roles
.ToList()
.Select(x => new SelectListItem
{
Text = x.Description,
Value = x.RoleID.ToString()
});
//Mapping that the automaper will take care of
model.UserID = user.UserID;
model.Username = user.Username;
model.RoleID = user.RoleID;
为了记录在案,以下是我在对 Jakub 回答的评论中所说的:
public static class EnumerableExtensions
{
public static IEnumerable<SelectListItem> ToSelectList<T, TTextProperty, TValueProperty>(this IEnumerable<T> instance, Func<T, TTextProperty> text, Func<T, TValueProperty> value, Func<T, bool> selectedItem = null)
{
return instance.Select(t => new SelectListItem
{
Text = Convert.ToString(text(t)),
Value = Convert.ToString(value(t)),
Selected = selectedItem != null ? selectedItem(t) : false
});
}
}
不用说,这非常简单,并且可以完成同样的事情(并且在属性路径不简单的情况下实际上更加健壮,因为 Jakub 的解决方案不适用于嵌套属性)。
(这不是一个真正的答案,我将其发布为社区维基只是为了帮助阐述一个观点)
控制器是填充视图模型的理想位置。
可以使用以下扩展方法删除管道代码:
public static class EnumerableExtensions
{
public static IEnumerable<SelectListItem> ToSelectList<T, TTextProperty, TValueProperty>(this IEnumerable<T> instance, Expression<Func<T, TTextProperty>> text, Expression<Func<T, TValueProperty>> value, Func<T, bool> selectedItem = null)
{
return instance.Select(t => new SelectListItem
{
Text = Convert.ToString(text.ToPropertyInfo().GetValue(t, null)),
Value = Convert.ToString(value.ToPropertyInfo().GetValue(t, null)),
Selected = selectedItem != null ? selectedItem(t) : false
});
}
public static PropertyInfo ToPropertyInfo(this LambdaExpression expression)
{
MemberExpression body = expression.Body as MemberExpression;
if (body != null)
{
PropertyInfo member = body.Member as PropertyInfo;
if (member != null)
{
return member;
}
}
throw new ArgumentException("Expression is not a Property");
}
}
model.Roles = context.Roles.ToSelectList(r => r.RoleID, r => r.Description);