4

我有一个带有几个静态方法的静态类。在这些方法中,我尝试使用HttpContext.Current. 例如:

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

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

有任何想法吗?

4

3 回答 3

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来找出链开始的位置/时间来解决问题,因此您不必进行我上面描述的更改 - 我只是推荐一种通用的方法,这将有助于在未来减少这些类型的“缺少单例”错误。

于 2010-03-11T16:20:27.060 回答
2

我遇到过几次,尤其是在另一个库中使用静态方法,而不是我的主要项目。当似乎没有其他方法起作用时,我求助于将 HttpContext 作为参数传递给静态方法。

于 2010-03-11T15:57:38.507 回答
0

究竟是在哪里抛出空异常?你调试过,看看什么是空的吗?HttpContext.Current 是 null 还是用户?

于 2010-03-11T02:14:25.190 回答