Response.Redirect (…)를 사용하여 양식을 새 페이지로 리디렉션하면 오류가 발생합니다.
mscorlib.dll에서 ‘System.Threading.ThreadAbortException’유형의 첫 번째 예외가 발생했습니다. mscorlib.dll에서
‘System.Threading.ThreadAbortException’유형의 예외가 발생했지만 사용자 코드에서 처리되지 않았습니다.
이것에 대한 나의 이해는 웹 서버가 response.redirect가 호출 된 페이지의 나머지 부분을 중단하여 오류가 발생한다는 것입니다.
Response.Redirect
endResponse라는 두 번째 매개 변수를 추가 할 수 있다는 것을 알고 있습니다 . endResponse를 True로 설정하면 여전히 오류가 발생하지만 False로 설정하면 그렇지 않습니다. 나는 그것이 웹 서버가 내가 리디렉션 한 나머지 페이지를 실행하고 있음을 의미한다고 확신합니다. 가장 적게 말하는 것은 비효율적 인 것 같습니다. 더 좋은 방법이 있습니까? 이외 Response.Redirect
또는 난을받지 않습니다 경우 정지 하중 이전 페이지를 강제하는 방법은 무엇입니까 ThreadAbortException
?
답변
올바른 패턴은 endResponse = false를 사용하여 리디렉션 오버로드를 호출하고 컨트롤을 반환 한 후 IIS 파이프 라인이 EndRequest 단계로 직접 진행해야한다고 호출하는 것입니다.
Response.Redirect(url, false);
Context.ApplicationInstance.CompleteRequest();
Thomas Marquardt 의이 블로그 게시물 은 Application_Error 핸들러 내에서 리디렉션의 특수 사례를 처리하는 방법을 포함하여 추가 세부 사항을 제공합니다.
답변
ASP.Net WebForms 에는이 문제에 대한 간단하고 우아한 해결책 이 없습니다Redirect
. Dirty 솔루션과 Tedious 솔루션 중에서 선택할 수 있습니다
Dirty : Response.Redirect(url)
브라우저로 리디렉션을 보낸 다음 ThreadAbortedException
현재 스레드를 종료 하기 위해 a 를 던집니다 . 따라서 Redirect () 호출 이후에는 코드가 실행되지 않습니다. 단점 : 나쁜 습관이며 이와 같은 스레드를 죽이는 성능에 영향을 미칩니다. 또한 ThreadAbortedExceptions
예외 로깅에도 나타납니다.
Tedious : 권장되는 방법은 호출 Response.Redirect(url, false)
한 다음 Context.ApplicationInstance.CompleteRequest()
코드 실행이 계속되고 페이지 수명주기의 나머지 이벤트 핸들러가 계속 실행되는 것입니다. 예를 들어 Page_Load에서 리디렉션을 수행하는 경우 나머지 핸들러가 실행될뿐만 아니라 Page_PreRender 등도 계속 호출됩니다. 렌더링 된 페이지는 브라우저로 전송되지 않으므로 추가 처리를 피할 수 있습니다. 예를 들어, 페이지에서 플래그를 설정 한 후 처리하기 전에 후속 이벤트 핸들러가이 플래그를 확인하도록합니다.
“문서는 CompleteRequest
” ASP.NET이 HTTP 파이프 라인 실행 체인에서 모든 이벤트와 필터링을 우회 하게한다 “고 설명합니다. 이것은 쉽게 오해 될 수 있습니다. 추가 HTTP 필터 및 모듈은 우회하지만 추가 이벤트는 우회하지 않습니다 현재 페이지 수명주기에서
더 깊은 문제는 WebForms에 추상화 수준이 없다는 것입니다. 이벤트 핸들러에있을 때 이미 출력 할 페이지를 작성하는 중입니다. 다른 페이지를 생성하기 위해 부분적으로 생성 된 페이지를 종료하기 때문에 이벤트 핸들러에서 경로 재 지정이 잘못됩니다. 제어 흐름이 렌더링 뷰와 분리되어 있기 때문에 MVC에는이 문제가 없으므로 뷰 RedirectAction
를 생성하지 않고 컨트롤러에서 단순히 a 를 반환하여 깔끔한 리디렉션을 수행 할 수 있습니다.
답변
늦어서 알고 있지만 나의 경우 나는 오직이 오류를 했어 Response.Redirect
에 Try...Catch
블록.
응답을 넣지 마십시오. Try … Catch 블록으로 리디렉션하십시오. 나쁜 습관이야
편집하다
@Kiquenet의 의견에 따라 Response.Redirect를 Try … Catch 블록에 넣는 대안으로 수행 할 작업이 있습니다.
방법 / 기능을 두 단계로 나눕니다.
Try … Catch 블록 내의 1 단계는 요청 된 작업을 수행하고 “결과”값을 설정하여 작업의 성공 또는 실패를 나타냅니다.
Try … Catch 블록 외부의 2 단계는 “결과”값에 따라 리디렉션을 수행하거나 수행하지 않습니다.
이 코드는 완벽하지는 않으며 테스트하지 않았으므로 복사해서는 안됩니다.
public void btnLogin_Click(UserLoginViewModel model)
{
bool ValidLogin = false; // this is our "result value"
try
{
using (Context Db = new Context)
{
User User = new User();
if (String.IsNullOrEmpty(model.EmailAddress))
ValidLogin = false; // no email address was entered
else
User = Db.FirstOrDefault(x => x.EmailAddress == model.EmailAddress);
if (User != null && User.PasswordHash == Hashing.CreateHash(model.Password))
ValidLogin = true; // login succeeded
}
}
catch (Exception ex)
{
throw ex; // something went wrong so throw an error
}
if (ValidLogin)
{
GenerateCookie(User);
Response.Redirect("~/Members/Default.aspx");
}
else
{
// do something to indicate that the login failed.
}
}
답변
Response.Redirect()
현재 요청을 중단하기 위해 예외를 발생시킵니다.
이 기술 자료 문서에서는 이 동작에 대해 설명합니다 ( Request.End()
및 Server.Transfer()
메소드 에도 해당 ).
들어 Response.Redirect()
과부하가 존재한다 :
Response.Redirect(String url, bool endResponse)
endResponse = false 를 전달 하면 예외가 발생하지 않습니다 (그러나 런타임은 현재 요청을 계속 처리합니다).
경우 endResponse 해당 = (또는 다른 오버를 사용하는 경우)에서, 예외가 발생되어 현재의 요청은 즉시 종료된다.
답변
여기 에 문제에 대한 공식적인 내용이 있습니다 (최신을 찾을 수는 없지만 이후 버전의 .net에서는 상황이 바뀌지 않았다고 생각합니다)
답변
이것은 Response.Redirect(url, true)
작동 방식입니다. ThreadAbortException
스레드를 중단하기 위해 를 던집니다 . 그 예외를 무시하십시오. (나는 그것이 어디에서 보이는 전역 오류 처리기 / 로거라고 생각합니까?)
흥미로운 관련 토론 은 Response.End()
해로운 것으로 간주됩니까? .
답변
또한 다른 솔루션을 시도했지만 리디렉션 후 일부 코드가 실행되었습니다.
public static void ResponseRedirect(HttpResponse iResponse, string iUrl)
{
ResponseRedirect(iResponse, iUrl, HttpContext.Current);
}
public static void ResponseRedirect(HttpResponse iResponse, string iUrl, HttpContext iContext)
{
iResponse.Redirect(iUrl, false);
iContext.ApplicationInstance.CompleteRequest();
iResponse.BufferOutput = true;
iResponse.Flush();
iResponse.Close();
}
따라서 리디렉션 후 코드 실행을 방지 해야하는 경우
try
{
//other code
Response.Redirect("")
// code not to be executed
}
catch(ThreadAbortException){}//do there id nothing here
catch(Exception ex)
{
//Logging
}