簡體   English   中英

無法獲得具有角色Asp.net MVC5身份的用戶2.2.1依賴注入

[英]Can't get Users with roles Asp.net MVC5 identity 2.2.1 dependency injection

大家好!

在閱讀了上一個問題的 MRebati提示之后,我搜索並了解了這個博客 ,不要混合統一和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:a

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();
            }
        }

感謝您的時間。

最好在UserManager保留對DbContext的引用:

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中獲得完整的樣本。 雖然我沒有正確測試它 - 我的數據庫暫時被打破 - (

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM