Ninject麻烦从WebContext获取UserName

时间:2013-09-17 10:36:54

标签: c# asp.net-mvc dependency-injection ninject httpcontext

你好我的网站有问题。有时在登录后,我的网站会将我重定向到登录页面,说我无权使用此功能,请登录。

好的,首先我想,我的Accesrights有些不对,但事实并非如此,如果我只是回到浏览器中的一个站点并再次发送请求,那就可以了。

所以我调试了它,经过大量的测试后我得到了一个结果,当我用Ninject创建我的服务上下文时,UserName是一个空字符串。

这是我的代码: 首先是我的Interface IServiceContext:

public interface IServiceContext
{
    string UserName { get; }
}

然后是Class ServiceContext:

public class ServiceContext : IServiceContext
{
    private static Object _syncRoot = new Object();
    private static long _instance = 0;
    private long _currentInstance = 0;

    public string UserName { get; private set; }

    public ServiceContext()
    {
        lock (_syncRoot)
        {
            if (_instance >= long.MaxValue)
                _instance = 0;
            _currentInstance = _instance++;
        }

        if (System.Web.HttpContext.Current.User == null)
            UserName = "";
        else
            UserName = System.Web.HttpContext.Current.User.Identity.Name;
    }

    public ServiceContext(string userName)
    {
        UserName = userName;
    }


    public override string ToString()
    {
        return string.Format("#{0}, UserName: {1}", _currentInstance, UserName);
    }
}

My Binding设置在一个单独的文件中,如下所示:

Bind<SecurityManagement >().ToSelf().InTransientScope();
Rebind<IServiceContext>().To<ServiceContext>().InRequestScope();

我需要使用重新绑定,因为在我的框架中,使用了一个用于serviceContext的StandardBinding。

来自我的InvokeMethod的电话:

class SecurityManagement : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        IServiceContext _context = _kernel.Get<IServiceContext>();
        String name = System.Web.HttpContext.Current.User.Identity.Name;
    }
}

所以有时它会发生,我的_context.UserName是一个空字符串。我发现在注入ServiceContext时System.Web.HttpContext.Current.User.Identity.Name属性是一个空字符串,但变量名称具有正确的用户名。我没有选择为我正在使用的框架的Property UserName公共原因制作setter。

所以任何人都知道为什么会这样?也许任何解决问题的想法

1 个答案:

答案 0 :(得分:1)

直接访问服务层和存储库层中的System.Web.HttpContext并不是一个好习惯,因为很难对项目进行单元测试。

相反,您希望通过构造函数注入HttpContextBase。

public class ServiceContext : IServiceContext
{ 
   HttpContextBase _httpContextBase,

   public ServiceContext(HttpContextBase httpContextBase)
   {
      _httpContextBase = httpContextBase;
   }
}

然后像这样访问用户 -

string username = _httpContextBase.User.Identity.Name;