2013-04-02 1 views
2

Сценарий

У меня есть проект ASP.NET, который использует метод пользовательской авторизации/аутентификации (по сравнению с использованием проверки подлинности форм/окон и т.д.). На каждом безопасный загрузки страницы, то выполняется следующий код:Как перенаправить браузер во время обратной пересылки Async?

protected void Page_Load(Object sender, EventArgs e) 
{ 
    if (!IsLoggedIn) 
    { 
     HttpContext.Current.Response.Redirect("~/Login/", true); 
    } 
} 

Этот код в основном проверяет, является ли пользователь еще вошли в систему (не просроченного сеанса ASP.NET, не вошедшего вне, и т.д.); если пользователь не вошел в систему, происходит Response.Redirect(), отправляя их на страницу входа.

Этот сценарий отлично работает, когда пользователь запрашивает полную страницу (по ссылке или по прямому URL). Проблема возникает при использовании async postback!

У меня есть кнопка, вложенная внутри <asp:UpdatePanel>, которая вызывает асинхронные обратные вызовы при нажатии. Эта кнопка обновляет <asp:Label />. Например:

<!-- the button --> 
<asp:LinkButton ID="MyButton" CausesValidation="false" Text="My Button" OnClick="MyButton_Click" runat="server" /> 

<!-- the label --> 
<asp:Label ID="MyLabel" runat="server" /> 
protected void MyButton_Click(Object sender, EventArgs e) 
{ 
    MyLabel.Text = DateTime.Now.ToString(); 
} 

Вопрос

При асинхронной постбэк выполняется, и IsLoggedIn ложно, то запрос перенаправляется на страницу входа в систему. Теперь ASP.NET Framework ожидает конкретного ответа (а не HTML-страницы); Таким образом, выбрасывая следующее сообщение об ошибке:

enter image description here

Вопрос

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

ответ

3

Если вы хотите, чтобы вызвать из кода, за что вы можете сделать это:

if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack) { 
    ScriptManager.RegisterStartupScript(updatepanelid, typeof(string), "redirect", "window.location = 'http://www.google.com';", true); 
} else { 
    Response.Redirect("http://www.google.com"); 
} 

Также обратите внимание, что если вы используете window.open(), откроется всплывающее окно (которое может быть или не быть заблокировано).Если вы используете window.location = "someurl";, он просто сделает перенаправление на стороне клиента.

+0

Хотя ваш ответ - самый подходящий способ достижения желаемого результата, мне было нужно немного больше ** больше **; Мне нужно ** прерывать ** жизненный цикл страницы в текущем состоянии (как «Response.Redirect (« путь »,« истина »)». Я добавил дополнительный ответ, содержащий дополнительную информацию. – Jesse

0

Здесь есть некоторая терминология. «Async postback» не является технически обратной почтой; это xmlHttpRequest. Если вы хотите сделать переадресацию здесь, это должно быть сделано в javascript в функции обратного вызова ajax, используя window.open().

Я не уверен, как реализовать это с помощью asp.net AJAX. Во время выполнения вашего xmlHttpRequest кода на сервере, это невозможно перенаправить клиента (уточнение - вы может перенаправить, но html, который вы ответите, будет (как в вашем случае) неправильно проанализирован javascript asp.NET .. Ajax код

с JQuery, это будет псевдо-решение

$.ajax({ 
    success: function(data) { 
     if (data == 'redirect') { 
      window.open('yourRedirectUrl'); 
     } 
    } 
}); 
+1

Спасибо за разъяснения по терминологии - К сожалению, я просто с помощью который широко используется в мире веб-приложений ASP.NET. И как бы я поймал эти переадресации? Как вы можете видеть, это * не * преднамеренные перенаправления, а побочный эффект авторизации/аутентификации. – Jesse

4

В то время как Kenneth's answer является подходящим методом перенаправления, мне нужно что-то немного больше изготовленный под заказ.

Во время асинхронной обратной передачи, мне нужно, чтобы имитировать Response.Redirect("path", true) - true параметр (Указывает ли выполнение текущей страницы следует прекратить) является важным вещь, мне нужно повторить! Просто использовать Response.End() после ScriptManager.RegisterClientScriptBlock() не получится, потому что в ответ браузер не будет откликаться.

Анализируя ответ сервера в асинхронном постбэка, я прибегал к использованию следующий хак (имитируя реакцию с помощью Response.Write):

String jsRedirect = String.Format("window.location.pathname = '{0}';", VirtualPathUtility.ToAbsolute(url)); 

Response.Write(
    // required parameters! 
    "0|asyncPostBackControlIDs|||" + 
    "0|postBackControlIDs|||" + 
    "0|updatePanelIDs|||" + 
    "0|childUpdatePanelIDs|||" + 
    "0|panelsToRefreshIDs|||" + 

    // your custom JavaScript 
    String.Format("{0}|scriptBlock|ScriptContentNoTags|{1}|", jsRedirect.Length, jsRedirect) 
); 
Response.Flush(); 
Response.End(); 
+0

Отличный ответ с большой детализацией. Действительно, с ограничением, которое вы хотите прервать обработку текущего запроса, это должен быть принятый ответ. – Oliver

Смежные вопросы