0

I have a class in my MVC5 application that deals with some user related functionality and has a dependency on HttpContext.Current.User as shown below

public interface IUser
{
  // return roles of currently logged in user
  string[] GetRoles;
}

public Class User : IUser
{
   private HttpContext context;

   // constructor 
   public User(HttpContext user)
   {
     this.context = user
   }

   // get roles
   public string[] GetRoles()
   {
     string username = this.context.User.Identity.Name;

     // get roles through some DB calls 
     string[] roles = someDbCalls();
     return roles;
   }
}

I have it setup for dependency injection using Ninject in NinjectWebCommon.cs as

kernel.Bind<IUser>().To<User>().WithConstructorArgument("user", x => HttpContext.Current);

This works fine if called from anywhere in my code except in my custom RolesProvider which is setup as shown below

public class CustomRoleProvider : RoleProvider
{
  [Inject]
  public IUser user {get; set;}

  public override string[] GetRolesForUser(string username)
  {
     return this.user.GetRoles();
  }
}

The call to GetRoles() from my custom role provider fails because HttpContext.Current.User injected by Ninject under this case is null. Any idea on what I may be doing wrong?

Edit: On further testing, it appears that the problem is with the way I am using Ninject in my custom Roles provider. Using the attribute injection as shown below

[Inject]
public IUser user {get; set;}

works only the first time and subsequent calls fail with HttpContext.Current.User is null error. I have fixed it in a hacky way by forcing the injection to happen each time I call the GetRoles method as shown below

public class CustomRoleProvider : RoleProvider
{
  private IUser user;

  public override string[] GetRolesForUser(string username)
  {
     // force ninject to inject a new instance of my interface
     var user = DependencyResolver.Current.GetService<IUser>();
     return user.GetRoles();
  }
}

Not sure why this works and so I am leaving this question open if someone can provide an explanation.

1 Answers1

0

It appears that by the time the role provider is called, the HTTPContext.Current is not yet set. This leads to other issues with custom RolesProvider (like the Null Reference Exception due to EtwTracing bug see: SqlRoleProvider on IIS8 Express ).

If you really need the HTTPContext.Current instead of using the Thread's PrincipalIdentity, you can setup your app to use compatibility mode. This appears to resolve the problem by setting up the HttpContext.Current sooner: https://social.msdn.microsoft.com/Forums/en-US/8ee88c92-5e8a-4c66-ace7-887eb500e1cb/httpcontextcurrent-always-been-null

Community
  • 1
  • 1
DeepV
  • 1