HttpContext.Current NullReferenceException в статическом методе - PullRequest
4 голосов
/ 11 марта 2010

У меня есть статический класс с несколькими статическими методами. В этих методах я пытаюсь получить доступ к контексту текущего потока, используя HttpContext.Current. Например:

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

Однако, когда я это делаю, я получаю NullReferenceException, печально известный «Ссылка на объект не установлена ​​на экземпляр объекта».

Есть идеи?

Ответы [ 3 ]

6 голосов
/ 11 марта 2010

Из исходного поста не ясно, что HttpContext на самом деле не хватает. Свойство HttpContext.User также может быть нулевым на определенных этапах жизненного цикла, что даст вам точно такое же исключение. Помимо всех других проблем, вам нужно пройтись по источнику и посмотреть, какая часть выражения на самом деле 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, чтобы выяснить, где и когда начинается цепочка, поэтому вам не нужно вносить изменения, которые я описал выше - я просто рекомендую общий подход, который поможет уменьшить количество подобных «пропущенных одноэлементных» ошибок в будущем.

2 голосов
/ 11 марта 2010

Я сталкивался с этим несколько раз, особенно со статическими методами в другой библиотеке, а не с моим основным проектом. Я прибегнул к передаче HttpContext статическому методу в качестве параметра, когда больше ничего не работает.

0 голосов
/ 11 марта 2010

Где именно выбрасывается нулевое исключение? Вы отлаживаете и видите, что является нулем? HttpContext.Current имеет значение null или пользователь?

...