Global_asax_BeginRequest - как эта строка ошибки? - PullRequest
0 голосов
/ 07 ноября 2018

В моем Global.asax.vb определено следующее ...

Private Sub Global_asax_BeginRequest(sender As Object, e As EventArgs) Handles Me.BeginRequest
    Try
        If Request IsNot Nothing Then 'this line throws an exception...
            With Request
                ...

Ошибка ...

ОШИБКА - Global_asax: System.NullReferenceException: ссылка на объект не установлен для экземпляра объекта.

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

Полагаю, что когда начинается запрос, за сценой должно происходить что-то еще, но я не знаю, как его отладить дальше.

Эта ошибка возникает не каждый раз. Я просто периодически вижу эти ошибки в журналах и не знаю, как они возникают. Я не могу воспроизвести это. Поскольку я не могу получить доступ к объекту Request, я не могу получить никакой другой информации о типе запроса, который его вызывает.

обновление ...

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

Public Sub Application_BeginRequest(sender As Object, e As EventArgs)
    Dim app As HttpApplication = TryCast(sender, HttpApplication)
    If app IsNot Nothing Then
        Dim _request = app.Request
...

На этот раз, что интересно, исключение произошло в этой строке ...

Dim app As HttpApplication = TryCast(sender, HttpApplication)

Это кажется очень странным, поскольку TryCast специально предназначен для исключения исключений.

Это полная трассировка стека, которую я получаю ...

System.NullReferenceException: Object reference not set to an instance of an object.
     at Global_asax.Application_BeginRequest(Object sender, EventArgs e) in C:\vs_agent\_work\4\s\...\Global.asax.vb:line 97
     at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
     at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
     at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Строка 97 соответствует строке TryCast.

Моя текущая теория заключается в том, что, возможно, это как-то связано с промежуточным ПО Owin

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

На всякий случай это полезно кому-то еще.

Я наконец-то понял, как воспроизвести ошибку. Это происходит, если я звоню без заголовка User-Agent. Вот так ...

curl -v -H 'User-Agent:' "https://[my_domain]/"

Путь для запроса, кажется, не имеет никакого значения.

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

Однако я не могу понять, почему запрос недоступен в Application_BeginRequest, но доступен в Application_Error.

0 голосов
/ 19 ноября 2018

Описанная ситуация не представляется возможной (я объясню позже), и я бы порекомендовал немного больше пуленепробиваемой диагностики, например

Try
  Dim locReq As HttpRequest = Request
Catch ex As Exception
   'record Exception with the complete stack trace
    Throw
End Try 

и используйте переменную HttpRequest (locReq) вместо свойства Request. Фрагмент также предотвращает изменение возвращаемого значения свойства Request.

Почему я считаю, что ваши предположения невозможны:

Невозможно получить NullReference в строке

If Request IsNot Nothing ...

но это может происходить из глубины свойства Request. Его (переведенный) исходный код является

Public Class HttpApplication
'...
    Public ReadOnly Property Request As HttpRequest
        Get
            Dim request As HttpRequest = Nothing
            If _context IsNot Nothing AndAlso
                 Not _hideRequestResponse Then request = _context.Request

            If request Is Nothing Then Throw New HttpException(SR.GetString(SR.Request_not_available))
            Return request
        End Get
    End Property

Здесь снова находится запрос свойства с (переведенным) исходным кодом

Public NotInheritable Class HttpContext
    '...
    Private _response As HttpResponse
    '...
    Public ReadOnly Property Response As HttpResponse
        Get
            If HideRequestResponse OrElse
               HasWebSocketRequestTransitionCompleted Then Throw New 
                  HttpException(SR.GetString(SR.Response_not_available))
            Return _response
        End Get
    End Property

Когда я читаю код, я не вижу места для нулевой ссылки, но может быть HttpException. Поэтому я пришел к выводу, что система регистрации ошибок неправильно записывает строку или исключение.

Обратите внимание на Интегрированный режим IIS7: запрос недоступен в этом контексте, исключение в Application_Start , которое связано с исключением Response_not_available.

Редактировать

Я попытался интерпретировать представленную трассировку стека. Мой вывод из самой глубокой процедуры ( ExecuteStep (шаг IExecutionStep, ref bool завершен синхронно) состоит в том, что исключение может возникнуть только в его блоке перехвата (переведено с оригинальными комментариями).

Catch e As Exception
        [error] = e
        'Since we will leave the context later, we need to remember if we are impersonating
         'before we lose that info - VSWhidbey 494476

        If ImpersonationContext.CurrentThreadTokenExists Then
            e.Data(System.Web.Management.WebThreadInformation.IsImpersonatingKey) = String.Empty
        End If
        'This might force ThreadAbortException to be thrown
        'automatically, because we consumed an exception that was
        'hiding ThreadAbortException behind it

        If TypeOf e Is ThreadAbortException AndAlso ((Thread.CurrentThread.ThreadState And ThreadState.AbortRequested) = 0) Then
            [error] = Nothing
            'Response.End from a COM+ component that re-throws ThreadAbortException
            'It is not a real ThreadAbort
             'VSWhidbey 178556
            _stepManager.CompleteRequest()
        End If
    End Try 

Отсюда кажется, что проблема действительно связана с прерыванием потока. Мои предположения таковы: _stepManager is nothing, но я понятия не имею, почему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...