在MVC角色提供程序中注入HttpContext.Current

时间:2014-06-09 16:38:36

标签: c#-4.0 asp.net-mvc-5 roleprovider ninject.web.mvc

我的MVC5应用程序中有一个类处理一些与用户相关的功能,并且依赖于HttpContext.Current.User,如下所示

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

我在NinjectWebCommon.cs中使用Ninject设置了依赖注入

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

如果从我的代码中的任何地方调用,除了我自定义的RolesProvider之外,这个工作正常,如下所示设置

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

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

从我的自定义角色提供程序调用GetRoles()失败,因为在这种情况下由Ninject注入的HttpContext.Current.User为null。关于我可能做错的任何想法?

修改 在进一步测试时,问题在于我在自定义角色提供程序中使用Ninject的方式。使用如下所示的属性注入

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

仅在第一次工作,后续调用失败,HttpContext.Current.User为null错误。我每次调用GetRoles方法时强制注入都会以一种hacky方式修复它,如下所示

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

不确定为什么会有效,所以如果有人可以提供解释,我会打开这个问题。

1 个答案:

答案 0 :(得分:0)

似乎在调用角色提供程序时,尚未设置HTTPContext.Current。这导致了自定义RolesProvider的其他问题(如由于EtwTracing错误导致的Null引用异常,请参阅:SqlRoleProvider on IIS8 Express )。

如果您确实需要HTTPContext.Current而不是使用Thread的PrincipalIdentity,则可以将应用程序设置为使用兼容模式。这似乎通过更快地设置HttpContext.Current来解决问题: https://social.msdn.microsoft.com/Forums/en-US/8ee88c92-5e8a-4c66-ace7-887eb500e1cb/httpcontextcurrent-always-been-null