2010-03-04 2 views
14

길고도 짧은 이야기, 나는 매우 특별한 상황에서, 디버깅과 어떤 점에서 시도하고 ASP.NET 응용 프로그램이 응용 프로그램은 내용의 Response.Redirect()에서 예외를 throw합니다 있습니다ASP.NET 응용 프로그램에서 HTTP 헤더가 전송 된 시점을 어떻게 알 수 있습니까?

"Cannot redirect after HTTP headers have been sent." 

어떤 I 더 많거나 덜 얻을 수 있습니다. 단 을 알아낼 수 없습니다. 여기서 헤더가 전송되었습니다.

ASP.NET 응용 프로그램에서 HTTP 헤더가 전송되었음을 나타내는 내용이 있습니까?

보너스의 어려움 : ASP.NET 응용 프로그램은 여전히 ​​.NET 1.1에 있습니다. 업그레이드 지연에 관한 상황은 정말 아픈 주제입니다.

+0

응답 버퍼링 ('Response.Buffer'을 - 당신이에 원하는) 및 응답 플러싱 ('Response.Flush를()'- 당신 돈 이것을하고 싶지 않다)는 두 가지 명백한 후보자이다. – bzlm

답변

15

HttpApplication은 헤더가 기록 될 때 호출되는 이벤트 PreSendRequestHeaders을 갖습니다. 이것을 구독하고 기록하거나 중단 점을 추가하십시오. 넘어

HttpResponseHeadersWritten (.NET 1.1 _headersWritten 필드)라는 내부 특성을 갖는다. 내부 용이므로 직접 액세스 할 수 없지만 리플렉션을 통해 수행 할 수 있습니다. 내부 디버깅 (프로덕션 코드가 아닌) 전용 인 경우 리플렉션을 사용하는 것이 좋습니다.

모든 페이지 수명주기 이벤트 전후에이 메소드를 점검하십시오. 어떤 이벤트가 헤더를 작성했는지 알았 으면, 더 많은 내용을 찾으려면 HeadersWritten 수표를 추가하십시오. 이 속성에 대한 수표의 점진적인 축소를 통해 찾을 수 있습니다.

새로운 정보

HeadersWritten 속성은 사무엘의 응답이 날 (+1)이 문제를 해결 닷넷 4.5.2

+0

이것은 정말 좋아 보인다 ... 나는이 응용 프로그램이 .NET 1.1에 있음을 잊어 버린 것을 제외하고 이것은 .NET 2.0+ 솔루션으로 보입니다. –

+0

@Schnapple, .NET 1.1은 정말로 오래되었습니다. 이전 버전에 대해 말할 때마다 항상 버전을 지정해야합니다. .NET 1.1에는 비공개 필드 인 _headersWritten이 있었으며,이 필드는 리플렉션을 통해 읽을 수 있습니다. –

+2

'HeadersWritten' 속성은 .Net 4.5.2에서 시작하는 공개입니다. –

5

에서 공공의 시작입니다. 내가 코멘트에서 코드 샘플을 붙여하지만 나는 그가 내을 IHttpHandler에 HeadersWritten 속성을 추가 제안 이벤트 사용 방법 다른 사람들을 돕는의 이익, 여기 수 없습니다 깰 것이라고 내 코드에서

protected bool HeadersWritten { get; private set; } 

void ApplicationInstance_BeginRequest(object sender, EventArgs e) 
{ 
    HeadersWritten = false; 
} 

void ApplicationInstance_PreSendRequestHeaders(object sender, EventArgs e) 
{ 
    HeadersWritten = true; 
} 

public void ProcessRequest(HttpContextBase context) 
{ 
    context.ApplicationInstance.PreSendRequestHeaders += new EventHandler(ApplicationInstance_PreSendRequestHeaders); 
    do_some_stuff(); 
} 

을 너무 늦게 헤더 나는 엉망이 단순히 먼저 HeadersWritten 속성 확인하는 경우 :

if (!HeadersWritten) 
{ 
    Context.Response.StatusDescription = get_custom_description(Context.Response.StatusCode); 
} 
+4

'HttpApplication' 객체의 각 인스턴스는 여러 개의 (그러나 순차적 인) 요청을 처리 할 수 ​​있으므로 BeginRequest 이벤트 중에 플래그를 재설정해야합니다. 이것은'IsReusable' 속성이 true를 리턴하는'HTTPHandler'에도 적용됩니다. [HttpApplication] (http://msdn.microsoft.com/en-us/library/system.web.httpapplication.aspx) 및 [IsResuable] (http://msdn.microsoft.com/en-us/library/)을 참조하십시오. system.web.ihttphandler.isreusable.aspx)에 대한 자세한 내용은 MSDN을 참조하십시오. –

+0

유로 카드 주셔서 감사합니다. 명확히하기 위해이 속성과 관련 코드 및 이벤트를 IHttpHandler에서 상속 한 클래스에 추가합니다. 이 클래스는이 요청에 대해 일회용이어야하며 다른 요청으로부터의 간섭으로부터 완전히 안전해야한다는 것을 이해했습니다. 이 이해가 정확하지 않으면 알려 주시기 바랍니다. –

+0

IHttpHandler 인터페이스의 멤버 중 하나는 IsReusable이라는 속성입니다 (원래 주석에서 잘못 입력했습니다). 구현이 본질적으로'public bool IsReusable {get {return false; }}', 그렇다면 괜찮습니다. ASP.NET은 요청마다 객체를 인스턴스화 한 다음 버립니다. 'true'를 반환하면 ASP.NET은 여러 요청에 대해 인스턴스를 재사용하며 스레드로부터 안전하지 않습니다. –

관련 문제