我正在使用Identity 2学习MVC,我正在采取一个示例项目并调整它以适应我正在尝试使用ASP.Net成员资格提供程序从WebForms转换的网站。
我现在遇到的问题是如何从另一个表中获取值以填充类中的属性。
我有一个名为AppUser.cs的类,它继承自IdentityUser。这基本上使用EntityFramework映射到名为“AspNetUsers”的表。我使用EF迁移向该表添加了更多属性(名/姓)。现在,我想显示用户分配的角色,最终需要获取可用角色列表并将其添加到下拉列表中。我将RoleName属性添加到我的AppUser类,但我假设因为该数据未存储在AspNetUsers表中,这就是为什么我收到错误“无效的列名'RoleName'”。
我如何在AppUser类中填充角色和/或获取可用角色列表,以便我可以在我的视图中显示它?
public class AppUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string RoleName { get; set; }
}
视图“Index.cshtml”上的模型是AppUser。
@model IEnumerable<AppUser>
这是我的Controller的ActionResult。
public ActionResult Index() {
return View(UserManager.Users);
}
private AppUserManager UserManager {
get {
return HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
}
}
这是AppUserManager.cs
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using SampleMvcSite.Models;
namespace SampleMvcSite.Infrastructure {
public class AppUserManager : UserManager<AppUser> {
public AppUserManager(IUserStore<AppUser> store)
: base(store) {
}
public static AppUserManager Create(
IdentityFactoryOptions<AppUserManager> options,
IOwinContext context) {
AppIdentityDbContext db = context.Get<AppIdentityDbContext>();
AppUserManager manager = new AppUserManager(new UserStore<AppUser>(db));
manager.PasswordValidator = new CustomPasswordValidator {
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = true,
RequireUppercase = true
};
manager.UserValidator = new CustomUserValidator(manager) {
AllowOnlyAlphanumericUserNames = true,
RequireUniqueEmail = true
};
return manager;
}
}
}
更新后的代码: 我最终创建了一个名为UserEditViewModel的类,我还包括我正在调整的示例项目中的AppRole类。
public class UserEditViewModel : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserRole { get; set; }
public IEnumerable<AppRole> AllRoles { get; set; }
}
public class AppRole : IdentityRole {
public AppRole() : base() { }
public AppRole(string name) : base(name) { }
}
然后在我的控制器中我做了以下事情。请记住,我只允许一次将用户分配给一个角色,因此理论上应该只有一个角色,这就是我只调用userRoles [0]的原因。由于我在一些示例用户之后添加了RoleManager,因此我有一些未分配给角色的用户。我添加了一个检查以确保角色有计数,如果不是,我将“用户”显示为他们的角色。如果没有找到任何角色,我将返回并添加代码以实际将用户添加到“用户”角色。
List<UserEditViewModel> UserList = new List<UserEditViewModel>();
var users = UserManager.Users;
foreach (AppUser user in users)
{
var userRoles = await UserManager.GetRolesAsync(user.Id);
string roleName = userRoles.Count() == 0 ? "User" : userRoles[0];
UserEditViewModel editUser = new UserEditViewModel();
editUser.UserName = user.UserName;
editUser.FirstName = user.FirstName;
editUser.LastName = user.LastName;
editUser.Email = user.Email;
editUser.UserRole = roleName;
editUser.AllRoles = RoleManager.Roles;
UserList.Add(editUser);
}
return View(UserList);
这是视图
<div class="form-group">
<label>Role:</label> @Html.DisplayNameFor(model => model.UserRole)
</div>
答案 0 :(得分:0)
我会看看ViewModels。在视图中更新实体模型通常是不好的做法 - 尤其是与安全相关的实体。见https://www.stevefenton.co.uk/2013/03/Why-You-Never-Expose-Your-Domain-Model-As-Your-MVC-Model/
使用viewmodel,您可以拥有一个List<Role>
的属性,您可以在控制器中填充并在视图中使用,另一个属性如RoleId用于用户的角色。
在POST中,您可以执行以下操作:
if (ModelState.IsValid)
{
var roleMgr = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var userMgr = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var role = roleMgr.FindById(viewmodel.RoleId);
if (role != null) userMgr.AddToRole(viewmodel.UserId, role.Name);
}
查看:
<div class="form-group">
@Html.LabelFor(model => model.RoleId)
<div class="col-md-2">
@Html.DropDownListFor(model => model.RoleId, Model.RoleList, htmlAttributes: new { @class = "form-control" })
</div>
<div class="col-md-10 col-md-offset-2">
@Html.ValidationMessageFor(model => model.RoleId, "", new { @class = "text-danger" })
</div>
</div>