所以,我在我的应用程序中实现ASP会员和角色管理。我还有第二个User表,其中包含所有与非会员资格相关的信息。我将E-mail设置为Membership中的用户名和User表中的外键。
我正在定制注册页面,以包括一个下拉菜单,以便在创建帐户时可以选择经理。通过查找角色为"Manager"的所有Membership用户,然后创建一个用户集合,其中外键与结果匹配,从而生成管理器列表。
List<string> managerNames = new List<string>(Roles.GetUsersInRole("Manager"));
var managers = from m in _db.Users where managerNames.Contains(m.Email) select m;
ViewBag.managers = managers;
现在,我必须使用该用户集合来填充视图中的下拉菜单,该下拉菜单将Name属性设置为"ManagerID"(以匹配我的RegistrationModel),每个选项的值设置为User的主键,下拉菜单中显示的文本显示User模型的DisplayName。
我可以遍历遍历"managers"集合并填充一个单独的SelectListItem,然后将SelectListItem传递给@Html.DropDown("ManagerID", newSelectListItem)
,但这似乎有些过分。是否有更直接(或可接受)的方法来做到这一点?
编辑
我添加了这个到我的控制器
var selectList = new List<SelectListItem>();
foreach (var manager in managers)
{
selectList.Add(new SelectListItem(){
Value = manager.UserID.ToString(),
Text = manager.DisplayName,
Selected = false
});
}
ViewBag.managers = selectList;
和这个到我的视图
@Html.DropDownList("ManagerID", (List<SelectListItem>)ViewBag.managers)
,它可以工作。这仍然是最好的方法吗?
这仍然是最好的方法吗?
。最好的方法是使用视图模型,忘记ViewBag/ViewData的存在。因此,从设计一个视图模型开始,它将满足您的视图的要求(显示管理器的ddl):
public class MyViewModel
{
[Required]
public int? SelectedManagerId { get; set; }
public IEnumerable<SelectListItem> Managers { get; set; }
}
然后让你的控制器动作填充这个视图模型并将其传递给视图:
public ActionResult Foo()
{
var managers = ... query your repository to get them
var model = new MyViewModel
{
Managers = managers.Select(x => new SelectListItem
{
Value = x.UserID.ToString(),
Text = x.DisplayName
})
};
return View(model);
}
最后在强类型视图中:
@model MyViewModel
...
@Html.DropDownListFor(
x => x.SelectedManagerId,
Model.Managers,
"-- Select a manager --"
)
所以每次你在ASP中使用ViewBag/ViewData。. NET MVC应用程序应该发出警报,告诉你有更好的方法。