大家好!
在阅读了来自MRebati的my previous question提示之后,我搜索并了解了这个blog不要混合统一和OWIN的重要性以及如何依赖注入ASP.net身份。
首先,我不想被标记为问同样的问题,即使我是,但现在我的代码与最后一个问题相比有所改变。
无论如何,现在我收到了一条不同的错误消息:
对象引用未设置为对象的实例。
这意味着在调用我的自定义Usermanager时我仍然是null。
我想要的结果是获得所有具有接受角色的用户的列表:
XXXXXX ------管理员
YYYYYY ------经理
关于我的项目的信息:
MVC:5.2.3
身份:2.2.1
实体框架:代码优先2.2.1
此外,我正在尝试使用Unity进行依赖注入。
这是我的代码:
控制器:
public ActionResult GetUsersWithRoles(string roleName)
{
ViewBag.UsersWithRoles = _userManager.GetUsersInRole(context, roleName);
return View(ViewBag.UsersWithRoles);
}
我在IdentityConfig.cs中的自定义用户管理器:
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
/// the create part which is moved from the default ///
public IQueryable<ApplicationUser> GetUsersInRole(ApplicationDbContext context, string roleName)
{
if (context !=null && roleName !=null)
{
var roles = context.Roles.Where(r => r.Name == roleName);
if (roles.Any())
{
var roleId = roles.First().Id;
return from user in context.Users
where user.Roles.Any(r => r.RoleId == roleId)
select user;
}
}
return null;
}
最后我的观点:
@using (Html.BeginForm("GetUsersWithRoles", "Roles"))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<h3>Roles for this user </h3>
foreach (IQueryables in ViewBag.UsersWithRoles)
{
<tr>
<td>@s</td>
</tr>
}
}
这是我的unityConfig.cs
using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using eCommerce.DAL.Repositories;
using eCommerce.Model;
using eCommerce.Contracts.Repositories;
using eCommerce.WebUI.Controllers;
using eCommerce.WebUI.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
namespace eCommerce.WebUI.App_Start
{
public class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
#endregion
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IRepositoryBase<Customer>, CustomerRepository>();
container.RegisterType<IRepositoryBase<Product>, ProductRepository>();
container.RegisterType<IRepositoryBase<Basket>, BasketRepository>();
container.RegisterType<IRepositoryBase<Voucher>, VoucherRepository>();
container.RegisterType<IRepositoryBase<VoucherType>, VoucherTypeRepository>();
container.RegisterType<IRepositoryBase<BasketVoucher>, BasketVoucherRepository>();
container.RegisterType<IRepositoryBase<BasketItem>, BasketItemsRepository>();
//container.RegisterType<AccountController>(new InjectionConstructor());
container.RegisterType<ApplicationDbContext>(new PerRequestLifetimeManager());
container.RegisterType<ApplicationUserManager>();
container.RegisterType <IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new InjectionConstructor(typeof(ApplicationDbContext)));
}
}
}
这是RolesController.cs的构造函数:
private ApplicationDbContext context;
private ApplicationUserManager _userManager;
public RolesController(ApplicationDbContext context, ApplicationUserManager _userManager)
{
this.context = context;
this._userManager = _userManager;
}
这是我的startup.cs: 一个
ssembly: OwinStartupAttribute(typeof(eCommerce.WebUI.Startup))]
namespace eCommerce.WebUI
{
public partial class Startup
{
internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
//app.CreatePerOwinContext(ApplicationDbContext.Create);
//app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>()); // <-
DataProtectionProvider = app.GetDataProtectionProvider();
}
}
}
这是我的Global.asax:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AreaRegistration.RegisterAllAreas();
var context = new ApplicationDbContext();
if (!context.Users.Any(user => user.UserName == "Email@hotmail.com"))
{
var userStore = new UserStore<ApplicationUser>(context);
var userManager = new UserManager<ApplicationUser>(userStore);
var applicationUser = new ApplicationUser() { UserName = "Email@hotmail.com" };
userManager.Create(applicationUser, "Password");
var roleStore = new RoleStore<IdentityRole>(context);
var roleManager = new RoleManager<IdentityRole>(roleStore);
roleManager.Create(new IdentityRole("Admin"));
userManager.AddToRole(applicationUser.Id, "Admin");
}
}
}
从我的rolesController创建方法:
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
context.Roles.Add(new IdentityRole
{
Name = collection["RoleName"]
});
context.SaveChanges();
ViewBag.ResultMessage = "Role created successfully !";
return RedirectToAction("Index");
}
catch
{
return View();
}
}
感谢您的时间。
答案 0 :(得分:0)
最好在UserManager
:
public class ApplicationUserManager : UserManager<ApplicationUser>
{
private readonly ApplicationDbContext context;
public ApplicationUserManager(ApplicationDbContext context, /*... other parameters*/) : base(store)
{
this.context = context;
//... other configuration bits
}
public IEnumerable<ApplicationUser> GetUsersInRole(string roleName)
{
if (String.IsNullOrWhiteSpace(roleName))
{
throw new ArgumentNullException(nameof(roleName));
}
var role = context.Roles.FirstOrDefault(r => r.Name == roleName);
if (role == null)
{
throw new Exception($"Role with this name not found: {roleName}");
}
var users = context.Users.Where(u => u.Roles.Any(r => r.RoleId == role.Id)).ToList();
return users;
}
// the rest of User manager methods
}
在你的控制器中避免使用ViewBag
- 这不是一个好习惯。此外,正如已经提到的那样,永远不要将IQueryable
传递给您的观点。粗略地说IQueryable
是一个SQL查询,但IEnumerable是一个对象的集合。视图只需要知道对象。所以你的控制器看起来像这样:
public class UsersWithRoleController : Controller
{
private readonly ApplicationUserManager userManager;
public UsersWithRoleController(ApplicationUserManager userManager)
{
this.userManager = userManager;
}
public ActionResult GetUsersWithRoles(string roleName)
{
var users = userManager.GetUsersInRole(roleName);
var viewModel = new GetUsersWithRolesViewModel()
{
RoleName = roleName,
Users = users,
};
return View(viewModel);
}
}
public class GetUsersWithRolesViewModel
{
public String RoleName { get; set; }
public IEnumerable<ApplicationUser> Users { get; set; }
}
视图将是:
@model IoCIdentity.Controllers.GetUsersWithRolesViewModel
@{
ViewBag.Title = "title";
}
<h2>List of users in role @Model.RoleName</h2>
<ul>
@foreach (var user in @Model.Users)
{
<li>@user.UserName</li>
}
</ul>
您可以在我的github中获取完整的示例。虽然我没有正确测试它 - 我的数据库目前已被打破 - (