2008-12-22 6 views
17

aspx-page에서 렌더링 한 HTML (내 로깅 용)을 가장 잘 캡처하려면 어떻게합니까?ASP.NET에서 생성 된 HTML 캡처

Response.Write를 사용하여 페이지에 다시 쓰고 싶지 않습니다. 사이트 레이아웃이 엉망이되어 버리기 때문입니다. Response.OutputStream 또는 경우 ArgumentException에서 Response.Output의 스트림 결과를 (. {System.ArgumentException : 스트림을 읽을 수 없었다)를 사용하여

+0

요약하면 페이지의 렌더링 방법을 재정의하십시오. 비슷한 질문과 대답 [here] (http://stackoverflow.com/questions/56279/export-aspx-to-html) –

답변

23

좋은 질문입니다. 나는 당신이 설명하는 것을하기 위해 HttpModule을 만들 수 있는지 알아봐야했습니다.

Responsream에서 읽으려고하는 행운이 없었지만 ResponseFilter를 사용하면 콘텐츠를 캡처 할 수있는 방법이 생겼습니다.

다음 코드는 꽤 잘 작동하는 것으로 보입니다. 아마 코드를 기반으로 사용할 수있을 것 같습니다. 그러나 이것이 내가 함께 던져 버린 것임을 기억하십시오. 그것은 어떤 방식 으로든 테스트되지 않았습니다. 적절한 검토/테스트 등을 거치지 않으면 어떤 프로덕션 환경에서도이를 사용하지 마십시오. 그래도 의견을 말하십시오.)

public class ResponseLoggerModule : IHttpModule 
{ 
    private class ResponseCaptureStream : Stream 
    { 
     private readonly Stream _streamToCapture; 
     private readonly Encoding _responseEncoding; 

     private string _streamContent; 
     public string StreamContent 
     { 
      get { return _streamContent; } 
      private set 
      { 
       _streamContent = value; 
      } 
     } 

     public ResponseCaptureStream(Stream streamToCapture, Encoding responseEncoding) 
     { 
      _responseEncoding = responseEncoding; 
      _streamToCapture = streamToCapture; 

     } 

     public override bool CanRead 
     { 
      get { return _streamToCapture.CanRead; } 
     } 

     public override bool CanSeek 
     { 
      get { return _streamToCapture.CanSeek; } 
     } 

     public override bool CanWrite 
     { 
      get { return _streamToCapture.CanWrite; } 
     } 

     public override void Flush() 
     { 
      _streamToCapture.Flush(); 
     } 

     public override long Length 
     { 
      get { return _streamToCapture.Length; } 
     } 

     public override long Position 
     { 
      get 
      { 
       return _streamToCapture.Position; 
      } 
      set 
      { 
       _streamToCapture.Position = value; 
      } 
     } 

     public override int Read(byte[] buffer, int offset, int count) 
     { 
      return _streamToCapture.Read(buffer, offset, count); 
     } 

     public override long Seek(long offset, SeekOrigin origin) 
     { 
      return _streamToCapture.Seek(offset, origin); 
     } 

     public override void SetLength(long value) 
     { 
      _streamToCapture.SetLength(value); 
     } 

     public override void Write(byte[] buffer, int offset, int count) 
     { 
      _streamContent += _responseEncoding.GetString(buffer); 
      _streamToCapture.Write(buffer, offset, count); 
     } 

     public override void Close() 
     { 
      _streamToCapture.Close(); 
      base.Close(); 
     } 
    } 

    #region IHttpModule Members 

    private HttpApplication _context; 
    public void Dispose() 
    { 

    } 

    public void Init(HttpApplication context) 
    { 
     _context = context; 

     context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute); 
     context.PreSendRequestContent += new EventHandler(context_PreSendRequestContent); 
    } 

    void context_PreRequestHandlerExecute(object sender, EventArgs e) 
    { 
     _context.Response.Filter = new ResponseCaptureStream(_context.Response.Filter, _context.Response.ContentEncoding); 
    } 

    void context_PreSendRequestContent(object sender, EventArgs e) 
    { 
     ResponseCaptureStream filter = _context.Response.Filter as ResponseCaptureStream; 

     if (filter != null) 
     { 
      string responseText = filter.StreamContent; 

      // Logging logic here 
     } 
    } 

    #endregion 
} 
+0

어딘가에 처음으로 어딘가에 있습니다. http://stackoverflow.com/questions/1020045/how-to-trace-scriptservice-webservice-requests에 필요한 것입니다. 감사! – jrummell

+0

PreRequestHandlerExecute가 HttpModule에서 실행되지 않았으므로 필터를 설정하기 위해 BeginRequest 이벤트를 사용해야했습니다. 나는 이유를 들여다 보지 않았지만 아마 다른 사람을 도울 것입니다. – JeremyWeir

+0

놀라운 솔루션! –

4
당신이 생성 된 HTTP 응답을 로그인 만에서 부담 할 수

많은 부하 테스터 ASP.NET의 경우 매우 큰 로그 파일 일 수 있습니다.

편집 : Response.Filter Tom Jelen의 코드는 이러한 종류의 감시를 제공하도록 설계되었으며 Response.Outputstream은 읽을 수 없습니다.

편집 2 : 페이지가 아닌 HttpModule을 들어

public class ObserverStream : Stream 
{ 
    private byte[] buffer = null; 
    private Stream observed = null; 

    public ObserverStream (Stream s) 
    { 
    this.observed = s; 
    } 

    /* important method to extend #1 : capturing the data */ 
    public override void Write(byte[] buffer, int offset, int count) 
    { 
    this.observed.Write(buffer, offset, count); 
    this.buffer = buffer; //captured! 
    } 

    /* important method to extend #2 : doing something with the data */ 
    public override void Close() 
    { 
    //this.buffer available for logging here! 
    this.observed.Close(); 
    } 

    /* override all the other Stream methods/props with this.observed.method() */ 

    //... 

} 

과를 Page_Load에서

(또는 응답이 어쨌든 기록 전) 서버 측 XMLHTTP을 할 수

Response.Filter = new ObserverStream(Response.Filter); 
+0

Response.OutputStream 또는 Response.Output의 스트림을 사용하면 ArgumentException ({System.ArgumentException : Stream 읽을 수 없습니다.) – lastas

+0

먼저 0 점을 찾으셨습니까? 읽을 수있는 MemStream에 쓰기? (그냥 VS 자신을 해고하는 방법이 지금 어떻게 해야할지 알고 싶습니다.) – annakata

+0

흠, 방금 전에 작성한 Response.Filter 코드를 게시 하려다가 Tom Jelen이 이미 완료했음을 발견했습니다. 나도 기본적으로 일했다 :) – annakata

1

한 가지 방법을 귀하의 서버에 요청하십시오. 결과를 잡고 파일이나 DB에 저장하십시오.

또는 클라이언트에서 AJAX를 사용하여 결과를 가져온 다음 서버에 다시 POST 할 수 있습니다.

+2

데이터를 두 배로 늘리면 요청이 두 배가됩니다. – annakata

관련 문제