Как определить, является ли текущий запрос асинхронной обратной передачей в событии ASP.NET Application_Error - PullRequest
6 голосов
/ 24 января 2012

Можно ли определить, является ли текущий запрос асинхронной обратной передачей (частичное обновление страницы) из события Application_Error?

Как лучше всего обрабатывать ошибки приложения при использовании асинхронных обратных передач?

В Application_Error мы перенаправляем на разные страницы ошибок, но это не работает должным образом, когда ошибка генерируется во время асинхронной обратной передачи. Мы заметили, что это верно даже тогда, когда AllowCustomErrorsRedirect = false, и у нас есть обработчик OnAsyncPostBackError для установки AsyncPostBackErrorMessage. Во время асинхронных обратных передач наш AsyncPostBackErrorMessage перезаписывается, и вместо этого клиент получает общую ошибку веб-страницы.

Ответы [ 3 ]

6 голосов
/ 24 января 2012

В методе Application_Error у вас больше нет прямого доступа к элементу управления <asp:ScriptManager> на странице. Поэтому уже слишком поздно обрабатывать событие AsyncPostBackError .

Если вы хотите предотвратить перенаправление, вам следует проверить запрос, чтобы узнать, является ли он фактически асинхронным. <asp:UpdatePanel> вызывает сообщение обратно со следующим заголовком HTTP:

X-MicrosoftAjax:Delta=true

(также см .: ScriptManager Включает AJAX в ваших веб-приложениях )

Проверка этого заголовка будет выглядеть примерно так:

HttpRequest request = HttpContext.Current.Request;
string header = request.Headers["X-MicrosoftAjax"];
if(header != null && header == "Delta=true") 
{
  // This is an async postback
}
else
{
  // Regular request
}

Относительно того, что было бы подходящим способом обработки исключения, - другой вопрос, имхо.

1 голос
/ 29 июня 2012

У меня был похожий сценарий.Для меня работал вызов Server.ClearError() в моем обработчике событий для ScriptManager AsyncPostBackError.Это предотвращает вызов функции Global.asax Application_Error.

0 голосов
/ 13 февраля 2013

В Application_Error вы можете получить доступ к ScriptManager, чтобы определить, является ли текущий запрос асинхронной обратной передачей.Глобальный объект HttpContext.Current.Handler фактически указывает на обслуживаемую страницу, которая содержит объект ScriptManager, который сообщит вам, является ли текущий запрос асинхронным.

Следующий оператор кратко иллюстрирует, как получить доступ к объекту ScriptManager.и получите эту информацию:

ScriptManager.GetCurrent(CType(HttpContext.Current.Handler, Page)).IsInAsyncPostBack

Конечно, этот оператор потерпит неудачу, если текущий запрос не для страницы или если на текущей странице нет ScriptManager, так что здесь есть более надежная парафункции, которые вы можете использовать внутри Global.asax для определения:

Private Function GetCurrentScriptManager() As ScriptManager
    'Attempts to get the script manager for the current page, if there is one

    'Return nothing if the current request is not for a page
    If Not TypeOf HttpContext.Current.Handler Is Page Then Return Nothing

    'Get page
    Dim p As Page = CType(HttpContext.Current.Handler, Page)

    'Get ScriptManager (if there is one)
    Dim sm As ScriptManager = ScriptManager.GetCurrent(p)

    'Return the script manager (or nothing)
    Return sm
End Function

Private Function IsInAsyncPostback() As Boolean
    'Returns true if we are currently in an async postback to a page

    'Get current ScriptManager, if there is one
    Dim sm As ScriptManager = GetCurrentScriptManager()

    'Return false if no ScriptManager
    If sm Is Nothing Then Return False

    'Otherwise, use value from ScriptManager
    Return sm.IsInAsyncPostBack
End Function

Просто вызовите IsInAsyncPostback () из Application_Error, чтобы получить логическое значение, указывающее текущее состояние.

Вы получаете универсальныйОшибки ASP.NET на клиенте, потому что попытка передать / перенаправить асинхронный запрос вызовет больше ошибок, заменяя и тем самым запутывая исходную ошибку.Вы можете использовать приведенный выше код для предотвращения передачи или перенаправления в таких случаях.

Также обратите внимание на еще одно обнаруженное мной открытие: даже если вы можете получить доступ к объекту ScriptManager, используя этот метод, по какой-то причине задайте его свойство AsyncPostBackErrorMessage из Application_Errorне работает.Новое значение не передается клиенту.Следовательно, вам все еще нужно обработать событие OnAsyncPostBackError ScriptManager в классе страницы.

...