静态方法中的 HttpContext.Current NullReferenceException

发布于 2024-08-24 21:00:36 字数 251 浏览 11 评论 0原文

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

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

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

有什么想法吗?

I have a static class with several static methods. In these methods, I'm trying to access the current thread's context using HttpContext.Current. For example:

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

However, when I do that, I receive a NullReferenceException, the infamous "Object reference not set to an instance of an object."

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薄荷港 2024-08-31 21:00:36

从原始帖子中尚不清楚 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 的堆栈跟踪来找出链开始的位置/时间即可解决问题,因此您不必进行更改我'如上所述 - 我只是推荐一种通用方法,它将有助于减少将来的此类“丢失单例”错误。

It isn't clear from the original post that the HttpContext is actually what's missing. The HttpContext.User property can also be null at certain stages of the lifecycle, which would give you the exact same exception. All other issues aside, you need to step through the source and see which part of the expression is actually null.

When you write code that references static methods/properties like HttpContext.Current, you have to write them knowing that your code isn't guaranteed to be run when the methods/properties are actually available. Normally you have something like this:

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

Although I suspect that this wouldn't really solve your problem here, it would just get rid of the exception. The issue is more likely that you're calling this method at a time or place when the context is simply not available, such as on a background thread, static constructor or field initializer, or in the Application_BeginRequest method, or some similar place.

I might start by changing the static methods to instance methods of a class that depends on an HttpContext instance (i.e. taken in the constructor). It's easy to fool yourself into thinking that methods like GetCurrentUserName are simple "utility" methods, but they're really not, and it is generally invalid to be invoking a method that references HttpContext.Current through the static property from any place where you don't already have an instance reference to the same HttpContext (i.e. from the Page class). Odds are, if you start rewriting your classes like this:

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

...then you will likely find out very quickly where the chain is being broken, which will be the point at which you need to reference HttpContext.Current because you can't get it from anywhere else.

In this specific case, obviously, you can solve the problem just by taking the stack trace of the NullReferenceException to find out where/when the chain begins, so you don't have to make the changes I've described above - I'm simply recommending a general approach that will help reduce these sorts of "missing singleton" errors in the future.

无妨# 2024-08-31 21:00:36

我已经遇到过几次这种情况,尤其是在另一个库而不是我的主项目中使用静态方法。当其他方法似乎不起作用时,我将 HttpContext 作为参数传递给静态方法。

I've run into this a few times, especially with static methods in another library and not my main project. I've resorted to passing the HttpContext to the static method as a param when nothing else seems to work.

海的爱人是光 2024-08-31 21:00:36

null 异常到底是在哪里抛出的?你调试过并看看什么是空的吗? HttpContext.Current 是 null 还是 User ?

Where exactly is the null exception being thrown? Have you debug and see what is null? Is the HttpContext.Current is null or the User?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文