0

I have an MVC app with custom membership and role providers. I am checking whether a user is in a role like this:

public static bool CustomersVisible
{
    get
    {
        return
            HttpContext.Current.User != null &&
            HttpContext.Current.User.Identity.IsAuthenticated &&
            HttpContext.Current.User.IsInRole("Admin");
    }
}

The custom Role provider looks like this:

public class DRRoleProvider : RoleProvider
{
    private IUserProfileRepository _userProfileRepository;
    private IRoleRepository _roleRepository;

    public DRRoleProvider() {}

    public DRRoleProvider(IUserProfileRepository userProfileRepository, IRoleRepository roleRepository)
    {
        _userProfileRepository = userProfileRepository;
        _roleRepository = roleRepository;
    }

. . .

public override bool IsUserInRole(string username, string roleName)
{
    var user = _userProfileRepository.GetByUserName(username);
    var role = _roleRepository.GetByName(roleName);

    if (user != null)
    {
        return user.Roles != null && user.Roles.Contains(role);
    }

    return false;
}

Edited to add: Here is my NinjectControllerFactory:

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel ninjectKernel;

    public NinjectControllerFactory()
    {
        ninjectKernel = new StandardKernel();
        AddBindings();
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        return controllerType == null
                   ? null
                   : (IController) ninjectKernel.Get(controllerType);
    }

    private void AddBindings()
    {
        ninjectKernel.Bind<ICustomerRepository>().To<CustomerRepository>();
        ninjectKernel.Bind<IUserProfileRepository>().To<UserProfileRepository>();
        ninjectKernel.Bind<IRoleRepository>().To<RoleRepository>();
        ninjectKernel.Bind<ISessionFactory>().ToProvider<SessionFactoryBuilder>().InSingletonScope();
        ninjectKernel.Bind<ISession>().ToMethod(CreateSession).InSingletonScope();

        ninjectKernel.Inject(Membership.Provider);
        ninjectKernel.Inject(Roles.Provider);
    }

    private ISession CreateSession(IContext context)
    {
        var session = context.Kernel.Get<ISessionFactory>().OpenSession();
        return session;
    }
}

When the IsUserInRole method is called, I get a null reference exception on the _userProfileRepository. How can I make sure the repositories get injected when called from HttpContext.Current.User.IsInRole? It works fine when called from my own code.

JeffCren
  • 396
  • 1
  • 5
  • 15

1 Answers1

1

RoleProvider is not really dependency-injection-friendly. It requires that you have default constructor. Try using property injection instead.

Since you are using Ninject, maybe these questions / answers could help:
Ninject with MembershipProvider | RoleProvider
Custom Role Provider using DI ninject throwing error

Community
  • 1
  • 1
Miroslav Popovic
  • 12,100
  • 2
  • 35
  • 47
  • I still get the same problem using property injection. I'm thinking it may have something to do with the request lifecycle - when I create a new customer and user it saves everything fine, but when the app redirects to the home page after creation and I try to check the roles, that's when the repositories are null. – JeffCren Jun 29 '12 at 01:12
  • The problem is most likely in your Ninject configuration. Could you update your question with it? Where do you tell Ninject to inject Role provider properties? In Application start? – Miroslav Popovic Jun 29 '12 at 01:20
  • I added the code from my NinjectControllerFactory, but I also noticed that the repositories are null all the time when using property injection, not just after a post and redirect. – JeffCren Jun 29 '12 at 01:30
  • The property injection was the right answer. The subsequent issue was due to the way I was instantiating the role provider. – JeffCren Jun 29 '12 at 03:05