You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC 5自定义RoleProvider无法获取用户角色问题求助

Fixing Custom RoleProvider Dependency Injection with Autofac in ASP.NET MVC5

Hey there, let's break down why your GoldenBodyProvider isn't pulling roles from the database correctly. The core issue here is how ASP.NET instantiates RoleProvider classes—it uses the parameterless constructor by default, which means your constructor with IUnitOfWork and IService never gets called. Those dependencies end up null when you try to use them in IsUserInRole.

Here's how to fix this step by step:

1. Adjust Your RoleProvider for Dependency Injection

First, modify your GoldenBodyProvider to use property injection and hook into the Initialize method to pull dependencies from Autofac after ASP.NET creates the instance:

namespace Web.Utility.Classes 
{
    public class GoldenBodyProvider : RoleProvider 
    {
        // Public properties for Autofac to inject
        public IUnitOfWork UnitOfWork { get; set; }
        public IService Service { get; set; }

        public override void Initialize(string name, NameValueCollection config)
        {
            base.Initialize(name, config);
            
            // Resolve dependencies from Autofac's container
            var container = DependencyResolver.Current.GetService<IContainer>();
            UnitOfWork = container.Resolve<IUnitOfWork>();
            Service = container.Resolve<IService>();
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            // Now you can safely use your dependencies here
            // Example implementation (adjust to your repository logic):
            var user = UnitOfWork.Users.FirstOrDefault(u => u.Username == username);
            if (user == null) return false;
            
            return user.Roles.Any(r => r.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase));
        }

        // Don't forget to implement all required abstract methods from RoleProvider
        public override string[] GetRolesForUser(string username)
        {
            var user = UnitOfWork.Users.FirstOrDefault(u => u.Username == username);
            return user?.Roles.Select(r => r.Name).ToArray() ?? Array.Empty<string>();
        }

        // Implement remaining abstract methods (fill in or throw NotImplementedException as needed)
        public override void CreateRole(string roleName) => throw new NotImplementedException();
        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) => throw new NotImplementedException();
        public override bool RoleExists(string roleName) => throw new NotImplementedException();
        public override void AddUsersToRoles(string[] usernames, string[] roleNames) => throw new NotImplementedException();
        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) => throw new NotImplementedException();
        public override string[] GetUsersInRole(string roleName) => throw new NotImplementedException();
        public override string[] GetAllRoles() => throw new NotImplementedException();
        public override string[] FindUsersInRole(string roleName, string usernameToMatch) => throw new NotImplementedException();
        public override string ApplicationName { get; set; }
    }
}

2. Ensure Autofac is Configured Correctly

Make sure your Autofac container registers your dependencies properly in Global.asax.cs or your dedicated Autofac config class:

var builder = new ContainerBuilder();

// Register MVC controllers
builder.RegisterControllers(typeof(MvcApplication).Assembly);

// Register your unit of work and service (adjust lifetimes to match your app's needs)
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
builder.RegisterType<Service>().As<IService>().InstancePerRequest();

// Set Autofac as the dependency resolver
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

3. Verify Web.Config Setup

Double-check that your custom role provider is enabled in web.config under <system.web>:

<system.web>
  <roleManager enabled="true" defaultProvider="GoldenBodyProvider">
    <providers>
      <clear />
      <add name="GoldenBodyProvider" type="Web.Utility.Classes.GoldenBodyProvider" />
    </providers>
  </roleManager>
</system.web>

Key Notes:

  • Why Property Injection? ASP.NET creates RoleProvider instances via the default constructor, so constructor injection won’t work. The Initialize method is the standard hook to resolve dependencies post-instantiation.
  • Implement All Abstract Methods: RoleProvider is an abstract class, so you need to implement every method—even if some throw NotImplementedException temporarily (fill in the ones your app actually uses).
  • Lifetimes: Using InstancePerRequest for IUnitOfWork is standard in MVC to ensure each request gets its own isolated unit of work instance.

Once you make these changes, your IsUserInRole method will have access to your database via the injected dependencies, allowing you to fetch and check user roles correctly.

内容的提问来源于stack exchange,提问作者arman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:12:39