(13) Razor 강좌 – 웹사이트 전체, 또는 폴더 내 파일 요청 시 항상 실행 되는 모듈
안녕하세요. SQLER의 김대우 입니다.
코난이와 함께하는 Razor & WebMatrix 시리즈 강좌리스트
(1) WebMatrix와 Razor! 이제 시작합니다.
(2) WebMatrix 설치부터 Hello World까지
(9) Razor 강좌 - Helper 소개(이미지, 비디오)
(12) Razor 강좌 – SMTP 메일전송(Live메일과 Gmail지원. SSL지원)
(13) Razor 강좌 – 웹사이트 전체, 또는 폴더 내 파일 요청 시 항상 실행 되는 모듈 (지금 보시는 내용)
(14) Razor 강좌 – SEO최적화 URL을 라우팅(Routing) 으로 구현
쓰다 보니 강좌가 조금씩 늘어나네요. 나름 꼭 필요할 내용으로 예상되어 두 개의 강좌를 추가 했습니다.
웹사이트를 개발하다 보면, 모든 페이지 요청에 대해 처리해야 하는 공통 모듈이 반드시 있습니다. 예를 들어, “데이터베이스 연결 문자열”과 같은 “전역변수”와 유사한 정보들을 처리해야 할 경우가 있습니다. 또는, 에러 처리 루틴을 폴더 별로 정의해 쓰기 원하실 경우에는 “폴더마다” 폴더 하위의 파일 실행 시마다 동작되길 원하는 처리가 있을 것입니다.
Razor에서는 웹사이트 전체 페이지 요청 시 동작하는 모듈 – “_start.cshtml”과 폴더 별로 요청 시 항상 처리되는 모듈인 “_inti.cshtml”이 존재합니다.
웹사이트 전체 아무 페이지나 요청 시 동작하는 모듈 “_start.cshtml”
강좌 내용 진행을 위해 꼭 아래 흐름을 이해 하시면 좋을 것 같아요.
사용자 요청이 들어올 때 만약 “_start.cshtml"이 존재하고, 처음 요청이 경우 실행하고, 이어서 요청된 페이지가 처리됩니다. “_start.cshtml" 파일이 존재하지 않거나, 처음 요청이 아닐 경우에는 실행되지 않습니다. (꼭 cshtml만 가능한 건 아닙니다. vbhtml도 당연히 됩니다. 편의상 cshtml로 적었습니다.^_^;;;)
주의
당연히, 모든 페이지 요청 시 실행되는 모듈이 _start.cshtml 파일에 오류가 있으면 전체 웹사이트 실행에서 오류가 발생할 수 있습니다. 사용에 주의 하세요.
참고
페이지 파일 앞에 ”_” 즉, 언더바가 있을 경우에 이 파일은 사용자의 직접적인 요청에 의해 실행되지 않습니다. 다른 파일 요청에 의한 참조로만 동작하게 됩니다.
그렇다면, 예제를 통해 살펴 보도록 하겠습니다.
@{
AppData["customAppName"] = "SQLER 웹사이트";
}
현재 웹사이트의 루트에 _start.cshtml 파일로 만들고 저장합니다.
@{
var appName = ApplicationInstance.Application["customAppName"];
}
<!DOCTYPE html>
<html>
<head>
<title>웹사이트의 이름을 보여 주세요~</title>
</head>
<body>
<h1> @appName</h1>
</body>
</html>
웹사이트의 루트에 AppName.cshtml 파일로 저장하고 실행합니다.
실행해보니 감이 오시죠? 제가 실행한 건 AppName.cshtml 파일인데 “_start.cshtml” 페이지에 전역으로 구성한 변수인 “customAppName”의 값을 불러와 개별 페이지에서 이용 가능합니다. 이렇게, 전역변수로 사용 가능한 처리를 이용하시면 유용합니다.
조금 실전적인(?) 전역변수 처리 예제를 소개해 드리려고 해요. 또 하나의 Helper인 reCAPTCHA Helper를 이용하는 예제를 살펴 보도록 하겠습니다.(캡차는 악의적인 봇을 걸러내 스팸 등을 사이트에서 실행하지 못하도록 사람인지 검사하는 기능입니다. 아마 사이트 댓글 쓰기나 포털 카페 가입 시 나오는 숫자나 단어를 넣으라는 처리 보셨을 거에요. 그게 캡차입니다.)
국내에서는 좀 뜸하지만, 해외에서 기본 캡차로 많이 쓰이는 reCAPTCHA를 이용해 볼게요. Helper하나 더 공부하는 셈~ 치시면 될 겁니다. 사용을 위해 등록을 해야 합니다. 사이트에 접속합니다. https://recaptcha.net – 웹사이트에 대해 계정을 생성(구글 계정 이용)하시면 publicKey와 PrivateKey 문자열이 나오게 됩니다. 이 문자열을 복사해 이용하시면 됩니다.
(참고로, Razor의 Helper는 Helper는 누구나 추가로 만들어 사용이 가능합니다.)
reCAPTCHA helper 사용에 필요한 문자열을 _start.cshtml 파일에 저장하고 사용하는 예제 입니다.
@{
// 국내외에서 캡차로 많이 쓰이는 reCAPTCHA 사이트에 접속합니다.
//https://recaptcha.net – 웹사이트에 대해 계정을 생성(구글 계정 이용)하시면
//publicKey와 PrivateKey 문자열이 나오게 됩니다.
//이 문자열을 복사해 이용하시면 됩니다.
ReCaptcha.PublicKey = "PublicKey 문자열을 복사해 넣으세요.";
ReCaptcha.PrivateKey = "PrivateKey 문자열을 복사해 넣으세요.";
}
루트 폴더에 위치한 _start.cshtml 파일을 위처럼 캡차 수행해 필요한 변수로 수정합니다.
@{
var showRecaptcha = true;
if (IsPost) {
if (ReCaptcha.Validate()) {
@:통과! 사람이군요!!!
showRecaptcha = false;
}
else{
@:너 봇이지?!
}
}
}
<!DOCTYPE html>
<html>
<head>
<title>캡차 처리 Test 페이지 - 단어를 정확히 입력하세요.</title>
</head>
<body>
<form action="" method="post">
@if(showRecaptcha == true){
if(ReCaptcha.PrivateKey != ""){
<p>@ReCaptcha.GetHtml()</p>
}
else {
<p>아마도 인증키가 틀리거나 오류가 있는 것 같습니다. 다시 확인해 보세요. </p>
}
}
<div>
<input type="submit" value="실행" />
</div>
</form>
</body>
</html>
Recaptcha.cshtml 파일로 저장하고 실행합니다.
단어를 넣고 처리가 되면 통과하게 됩니다. – 이렇게 간단히 _start.cshtml를 이용한 전역변수 처리를 알아 보았습니다. 다음은 웹사이트 전체가 아니라, 폴더 내 파일들에 대한 처리를 알아보도록 할게요.
"폴더" 내 파일 요청 시 항상 실행 되는 모듈 - “_init.cshtml”
전체 웹사이트에 대해 처리되는 공통모듈인 _start와 달리 "폴더" 하위에 위치하는 페이지 파일들에 대해서만 처리될 필요가 있는 경우가 있습니다. 이때 사용하는 처리가 “_init.cshtml”입니다. 웹 개발 경험이 있는 분들은 바로 감이 딱 오실 거에요. 이 녀석이 사용되는 대표적인 경우도 느낌이 오시죠? 예~ 바로 사용자 정의 에러처리 일거에요. 흐름은 어렵지 않습니다. 아래를 꼭 이해해 주세요.
_start 처리 모듈은 위에서 설명해 드린 것과 같습니다. 이어서, 폴더 안에 _init.cshtml 파일이 위치하게 되면 해당 파일을 실행하고 실행 후에 사용자가 요청한 페이지가 실행되게 됩니다.
_start와 달리 _init에서는 “RunPage()”를 실행해 요청될 페이지를 그 위치에서 실행하게 됩니다. – 왜 이런 경우가 있는고 하니, 개발 경험이 있는 분이라면 에러 핸들 시 try에서 시도할 경우 입니다. 감이 팍팍 오시죠? 그럼 간단한 예제를 통해 살펴 보도록 하시지요.
@{
PageData["Color1"] = "빨강색";
PageData["Color2"] = "파랑색";
}
웹사이트 루트에 _init.cshtml 파일을 만들고 저장합니다.
@{
PageData["Color2"] = "노랑색";
PageData["Color3"] = "초록색";
}
InitPages라는 폴더를 만들고 이 폴더에 _init.cshtml로 저장합니다.
@PageData["Color1"]
<br/>
@PageData["Color2"]
<br/>
@PageData["Color3"]
InitPages 폴더에 default.cshtml 파일을 만들고 실행합니다.
InitPages 폴더의 페이지를 요청했는데 루트 폴더의 _init 파일과 InitPages 폴더의 _init 파일이 모두 실행됩니다. 그럼 Color2는 어떻게 나오나요? 계층 처리로 종단에 위치한 값, “노랑색”이 출력됩니다. 감이 오시지요? 그렇다면, 기대하고 있으실 에러 핸들 처리를 해 보도록 할게요.
_init을 이용한 폴더 내 페이지 실행 시 에러 처리 모듈
<!DOCTYPE html>
<html>
<head>
<title>오류가 발생했습니다.</title>
</head>
<body>
<h1>SQLER 고객님 불편을 드려 죄송합니다. 조속히 오류를 해결 하겠습니다.</h1>
<p> 이 페이지에서 오류가 발생 했습니다. @Request["source"]</p>
</body>
</html>
웹사이트 루트 폴더에 Error.cshtml 파일로 저장합니다.
@{
try
{
RunPage();
}
catch (Exception ex)
{
Response.Redirect("~/Error.cshtml?source=" +
HttpUtility.UrlEncode(Request.AppRelativeCurrentExecutionFilePath));
}
}
루트 폴더에 InitCatch 폴더를 만들고 _init.cshtml 파일로 저장합니다.
@{
var db = Database.OpenFile("오류 유발 - 없는 DB를 열기 위해 시도");
}
InitCatch 폴더에 Exception.cshtml 파일로 저장합니다.
이어서, 에러를 발생시키는 Exception.cshtml 파일을 실행하세요.
감이 오시는지요? InitCatch 폴더의 _init 중간 RunPage()가 수행되어 요청된 페이지인 Exception.cshtml 이 실행 됩니다. 오류가 발생하고 오류는 핸들 되어 루트의 error페이지로 redirect되며 쿼리문자열로 에러 페이지 정보를 전달하게 됩니다. error.cshtml 페이지는 넘겨받은 에러 페이지 정보를 출력하게 됩니다.
여담으로, 웹 개발자 분들을 위한 참고
이렇게 폴더 내 오류 처리와 같은 모듈을 쉽게 사용가능 한 처리가 _init.cshtml 입니다. 만약, 웹 개발 경험이 많으시고 좀더 다듬어진 error를 구현하고 싶다면, 적절히 error 핸들 페이지에 catch된 exception 개체의 에러 정보를 string으로 변환해 넘겨서 가공 후 사용자에게 보여주고, 이어서 관리자에게 오류에 대해 자동 알림 기능(SMTP메일이나 SMS전송)도 가능할 겁니다.
도움 되시길 바라며, 다음 강좌에서 뵙겠습니다.
참고자료 :
(1) WebMatrix와 Razor! 이제 시작합니다.
(2) WebMatrix 설치부터 Hello World까지
(3) Razor 강좌 - 기본 구문 및 주석 처리
(4) Razor 강좌 - 코드 블록과 POST 처리
(5) Razor 강좌 - 재사용 가능한 코드 생성
(6) Razor 강좌 - 레이아웃 페이지 구조 처리
(7) Razor 강좌 - 파일처리, 파일 업로드
(8) Razor 강좌 - 데이터베이스 처리
(9) Razor 강좌 - Helper 소개(이미지, 비디오)
(10) Razor 강좌 – 디버깅
(11) Razor 강좌 - 캐시 처리
(12) Razor 강좌 – SMTP 메일전송(Live메일과 Gmail지원. SSL지원)
[동영상 강좌] (1) WebMatrix 첫 실행 & Hello World까지 달려요~
[동영상 강좌] (2) WebMatrix 5분 리뷰~
[동영상 강좌] (3) Razor 강좌 - 기본 구문 및 주석 처리
[동영상 강좌] (4) Razor 강좌 - 코드 블록과 POST 처리
https://www.asp.net/webmatrix/tutorials/15-customizing-site-wide-behavior
사용자가 직접 Helper를 만들고 사용하는 방법 – 영문