안녕하세요. 즈믄입니다. 귀차니즘의 심각함을 적나라하게 표현하는 이유로, 계속 잠만자다가 느닷없이 하나 올려봅니다.(아무 이유없어~)

부실하지만 도움이 되었으면 합니다. ^^


참으로 쓸만한 HttpWorkerRequest Class

Cross-Page Posting

근무환경이 바뀌면서, 다시 웹 프로젝트를 시작하게 되었다. 한동안 손을 놓고 있었던 지라, 제대로 어색한 이 분위기

스스로 뇌가 가벼워지는 느낌을 받기 시작하면서, 다시 ASP.NET을 차근차근 보기 시작했다. ASP.NET 2.0 Feature를 슬슬 훑어보다가, Cross-Page Posting이란 기능을 보면서, 슬슬 가벼운 날 코딩을 시작했다. 이 기능에 대해 많이들 알겠지만 대략 요점을 말하자면, a.aspx페이지에서 Button Click 이벤트로 서버에 요청이 전달될 때, Button 클래스에 정의된 PostBackUrl 속성에 특정(b.aspx) 페이지를 명시하면, 서버는 PostBackUrl에 정의된 페이지를 열게 되는데, 이때 b.aspx 페이지는 자신을 열게 한 페이지에 대한 정보를 가지고 있는데, 이 객체가 PreviousPage되겠다.

이에 대한 예제 코드는 아래와 같다.

a.aspx

<form id="form1" runat="server">

<div>

<asp:Button ID="btn1" runat="server" PostBackUrl="~/Default2.aspx" Text="Close Page Posting Test" />

</div>

</form>

b.aspx

<script runat="server">

protected void Page_Load(object sender, EventArgs e)

{

if (PreviousPage != null)

{

Response.Write("Cross Page Posting 발생했습니다.");

}

}

</script>

그런데, 여기에서 이전 페이지 즉 PreviousPage에 대한 경로를 가져온다고 생각해보자. 어떻게 해야 할까? 확인해보면 알겠지만, PreviousPageSystem.Web.UI.Page 타입의 객체이다. 그러므로 자신을 호출한 Url정보를 당연히 가지고 있을 것이다. 이것을 궁금해하는 분들이 있을 같아서, 한번 거들떠보고 지나가자. 이것을 알려면 먼저 ASP.NET 페이지를 요청할 , 어떤 절차로 처리가 되는지를 알아야 한다.

사용자 삽입 이미지

asp.net Request Process

위 그림을 보면 한 눈에 이해할 수 있을 것이다. Client IIS를 통해 특정 ASP.NET 페이지를 요청하게 되면 ASP.NET 처리기는 요청된 Url로 페이지를 찾게 되고, 그 이후에 CLR에 의해 Application Domain이 생성되고, HttpRuntime객체가 생성 된 후, HttpRequest, HttpResponse 객체를 가지고 있는 HttpContext 객체와 HttpApplication 객체가 초기화 된다. 여기에서 요청 받은 Page는 위에 초기화 된 객체들의 정보를 사용 할 수 있고, 이러한 정보를 통해 앞서 말한 PreviousPage에 대한 경로를 확인 할 수 있는 것이다.

그럼 이런 내용을 간략히 코드로 정리해보자.

b.aspx

if (PreviousPage != null)

{

Response.Write(HttpContext.Current.Request.UrlReferrer.AbsoluteUri);

}

코드를 보면 알겠지만, 정말 간단하다. Client가 요청한 페이지는 HttpContext 객체 안에 존재하기 때문에, Request에 대한 정보를 참조하면 되는 것이고, 현재의 HttpContext로 들어온 Request 정보 중에 UrlReferrer 속성을 가져오는 것 이라고 간략히 풀어 말할 수 있겠다.

(참고로 UrlReferrer 속성은 .Net Framework v2.0에서 추가되었다.)

HttpWorkerRequest Class

그런데, UrlReferrer라는 것이 생각해보면 b.aspx 페이지 안에서 호출된 속성인데, 왜 자신을 열게 한 PreviousPage Url 정보를 가져올까? 라는 생각이 슬금슬금 나올 수 있다. (본인만 그런가? -_-;) 그래서 저 UrlReferrer란 놈을 까보게 되었고, 이를 확인해 보니 내막은 이러했다.

ASP.NET 처리기에 의해 여차여차해서 생성된 HttpContext 객체는 생성될 때 인자로 Request Response 객체를 인자로 받게 된다. 이렇게 전달받은 Request 객체는 UrlReferrer 속성에 get Property을 구현하고 있는데, 여기에서 사용되는 것이 HttpWorkerRequest Class이다. 그럼 이 HttpWorkerRequest Class란 놈은 무엇을 하는 놈이냐에 대해서 MSDN을 인용하자면

추상 클래스는 ASP.NET 관리 코드에서 요청을 처리하는 사용되는 기본 작업자 메서드 열거형을 정의합니다.(http://msdn2.microsoft.com/ko-kr/library/system.web.httpworkerrequest(VS.80).aspx)

라고 되어 있다. 참으로 간단하면서, 쉽게 알 수 없는 문장인 듯 하다.

이것을 나름 이해하기 편하게 말하자면, “ASP.NET 페이지 요청에 대한 Header 정보와 ASP.NET 처리기가 사용하는 구성정보를 포함하고 있어서, ASP.NET 처리기가 이 정보를 사용한다.” 라는 내용일 것 같다.

여기에서 다시 UrlReferrer란 놈에 대해서 다시 이야기해보면, UrlReferrer 속성이 return하는 Uri정보는 이 HttpWorkerRequest 객체가 처리해서 던져주는 것이다. HttpRequest 객체는 이 HttpWorkerRequest 객체를 멤버로 가지고 있고, UrlReferrer 속성을 누군가가 호출했을 때, HttpWorkerRequest 객체가 가지고 있는 Header 정보를 이용해서 Uri정보를 던져주는 것이다.

Uri에 해당하는 Header 정보를 가져오는 HttpWorkerRequest 객체의 속성은, Static으로 선언된 HttpWorkerRequest.HeaderRefer이란 속성이 return하는 Header 정보의 index(int)을 이용해, GetKnownRequestHeader(int index) 메소드를 호출해서 가져올 있다.

실제로 HttpWokerRequest Class 멤버를 보면, 많은 Header 정보와 구성 정보를 가져 있다. 이러한 것은 직접 확인해 보기 바란다. 언제 어느때 정말 유용하게 사용 있기때문이다.

그런데, 세상에 쉬운게 없듯이 객체를 사용하는게 그리 쉽지많은 않다. 왜냐하면, 객체를 생성하게 되면, 단지 HttpWorkerRequest 객체만을 초기화 하는 것이다. 우리가 객체를 사용하는 이유는, 현재 요청에 대한 갖가지 Header 정보와 구성 정보를 사용하기 위해 사용하는 것인데, new 통해 초기화된 HttpWorkerRequest 객체는 현재 요청에 대한 정보를 하나도 가지고 있지 않기 때문이다. 무슨 소리인가그럼 여태껏 본인은 소용없는 썰을 푼것인가

그건 아니다. 우리 개발자들은 끈기와 집념의 소속 집단 아닌가~ 이제부터 현재 요청에 대한 HttpWorkerRequest 정보를 사용 있는 방법을 알아보자.

일단, 먼저 시선을 돌려야 것은 HttpContext 객체이다. 이유는, HttpContext 객체가 생성이 되어야 현재 요청에 대한 HttpWorkerRequest 객체가 제공하는 여러 정보를 활용 있기 때문이다. (이것이 이해가 되지 않는 분들은 그림부터 밑으로 차근차근 읽어보기 바란다.)

여기에서 새롭게 등장하는게 IServiceProvider 인터페이스이다.

HttpContext 객체는 IServiceProvider 인터페이스를 구현하고 있다. 그리고 IServciceProvider 인터페이스는 GetService(Type type)이라는 메소드를 선언하고 있는데, 이를 통해서 현재 요청에 대한 HttpWorkerRequest 객체를 가져 있다.

거두절미하고 아래 코드를 보자

IServiceProvider serviceProvider = (IServiceProvider)HttpContext.Current;

HttpWorkerRequest wr =

(HttpWorkerRequest)serviceProvider.GetService(typeof(HttpWorkerRequest));

string referrerInfo = wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderReferer);

Response.Write(referrerInfo);

이 코드는 IServiceProvider 인터페이스를 구현한 HttpContext 객체를 이용해 IServiceProvider 인터페이스의 참조를 얻고, GetService 메서드를 통해 인자로 할당한 HttpWorkerRequest Type을 이용해 HttpWorkerRequest 객체의 참조를 반환 받는다. 확인해 보지는 않았지만, GetServcie 메서드는 내부적으로 Reflection을 이용해 인자로 넘어온 Type에 대한 참조를 반환하리라 예상이 된다.

이렇게 반환된 HttpWorkerRequest 객체의 참조를 이용해, GetKnownRequestHeader 메소드 호출로 여러 가지 Header 정보를 확인 할 수 있다.

이 코드의 결과는 HttpContext.Current.Request.UrlReferrer.AbsoluteUri 값과 동일하다.

여기에서는 Cross-Page Posting에서 생긴 궁금점에 대한 것을 대상으로 예제코드와 설명을 진행했지만, 외에도 나름 도움이 될만한 정보들을 많이 확인 있으니, 쓸만한 객체로 생각이 된다.

이것으로 소개를 마치겠습니다. 부족한 점이 많을것으로 생각이 됩니다. 부분은 앞으로 진행하면서 보완하도록 노력하겠습니다. ^^

그리고 혹여, 잘못된 설명이 있다면 바로 알려주세요. 확인 정정해서 공지토록 하겠습니다.

감사합니다. ~

'ASP.NET' 카테고리의 다른 글

VS 2008/.Net Framework 3.5 Beta2 출시  (0) 2007.08.25
Web.Config 설정  (0) 2007.07.31
ASP.NET 2.0에서 달라진 기능  (0) 2007.07.07
Enterprise Library  (0) 2007.05.31
MS Silverlight 강의 동영상 풀버전  (0) 2007.05.21
Posted by 퓨전마법사
,