静态方法中的HttpContext.Current NullReferenceException

Jas*_*ord 4 asp.net session static-methods httpcontext nullreferenceexception

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

var userName = HttpContext.Current.User.Identity.Name;
Run Code Online (Sandbox Code Playgroud)

但是,当我这样做时,我会收到一个NullReferenceException臭名昭着的"对象引用未设置为对象的实例".

有任何想法吗?

Aar*_*ght 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;
}
Run Code Online (Sandbox Code Playgroud)

虽然我怀疑这不会真正解决你的问题,但它只会摆脱异常.问题更可能是您在上下文根本不可用的时间或地点调用此方法,例如在后台线程,静态构造函数或字段初始化程序或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;
    }
}
Run Code Online (Sandbox Code Playgroud)

......那么你很可能会发现非常迅速,其中链正在被打破,这将是在你需要参考点HttpContext.Current,因为你无法从其他地方得到它.

在这个特定的情况下,显然,您可以通过获取NullReferenceException链的跟踪来找出链开始的位置/时间来解决问题,因此您不必进行上面描述的更改 - 我只是推荐一种有助于减少未来"丢失单身"错误的一般方法.