静态方法中的HttpContext.Current NullReferenceException

时间:2010-03-11 02:12:28

标签: asp.net session static-methods httpcontext nullreferenceexception

我有一个带有几个静态方法的静态类。在这些方法中,我试图使用HttpContext.Current访问当前线程的上下文。例如:

var userName = HttpContext.Current.User.Identity.Name;

然而,当我这样做时,我收到一个NullReferenceException,臭名昭着的“对象引用未设置为对象的实例。”

有什么想法吗?

3 个答案:

答案 0 :(得分:6)

原帖中并不清楚HttpContext实际上是缺少什么。 HttpContext.User属性在生命周期的某些阶段也可以为null,这将为您提供完全相同的异常。除了所有其他问题之外,您需要逐步查看源代码并查看表达式的哪一部分实际为null

当您编写引用静态方法/属性(如HttpContext.Current)的代码时,您必须编写它们,因为它们知道在方法/属性实际可用时不能保证运行代码。通常你会有这样的事情:

static string GetCurrentUserName()
{
    HttpContext context = HttpContext.Current;
    if (context == null)
        return null;
    IPrincipal user = context.User;
    if (user == null)
        return null;
    return user.Identity.Name;
}

虽然我怀疑这不会真正解决你的问题,但它只会摆脱异常。问题更可能是您在上下文根本不可用的时间或地点调用此方法,例如在后台线程,静态构造函数或字段初始化程序或Application_BeginRequest方法或某些方法中类似的地方。

我可能首先将静态方法更改为依赖于HttpContext实例的类的实例方法(即在构造函数中使用)。很容易欺骗自己认为像GetCurrentUserName这样的方法是简单的“实用”方法,但它们实际上并非如此,并且通过静态属性调用引用HttpContext.Current的方法通常是无效的。从任何你没有实例引用相同HttpContext(即来自Page类)的地方。如果你开始重写这样的课程,那么可能性很小:

public class UserResolver
{
    private HttpContext context;

    public UserResolver(HttpContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");
        this.context = context;
    }

    public string GetUserName()
    {
        return (context.User != null) ? context.User.Identity.Name : null;
    }
}

...那么你很可能会在链条被破坏的地方快速找到非常,这将是你需要引用HttpContext.Current的点,因为你无法获得它来自其他任何地方。

在这个特定的情况下,显然,您可以通过获取NullReferenceException的堆栈跟踪来找出链开始的位置/时间来解决问题,因此您不必进行更改I'如上所述 - 我只是建议采用一种通用的方法来帮助减少将来出现的“丢失单身”错误。

答案 1 :(得分:2)

我已经遇到过这种情况,特别是在另一个库中使用静态方法,而不是我的主项目。当没有别的东西似乎有效时,我已经将HttpContext传递给静态方法作为参数。

答案 2 :(得分:0)

究竟是什么抛出了null异常?你有调试,看看什么是null? HttpContext.Current是null还是User?