login register Sysop! about ME  
qrcode
    최초 작성일 :    2012년 07월 10일
  최종 수정일 :    2012년 07월 10일
  작성자 :    Anne
  편집자 :    Anne (김 태영)
  읽음수 :    42,809

강좌 목록으로 돌아가기

필자의 잡담~

이번 컬럼은 taeyo와 동명이인이신~ 김태영(Anne)님이 번역해 주셨으며, MVC View에서 사용되는 Razor 구문에 대한 전반적인 내용을 설명하고 있습니다. 원문은 http://www.asp.net/mvc/tutorials/views/introduction-to-razor-syntax 입니다.

이 글은 MVC 공식 자습서 중 http://www.asp.net/mvc/tutorials/views/introduction-to-razor-syntax 의 글을 편역한 내용입니다. 마이크로소프트의 공식 번역 문서가 아니며 태오 사이트 MS 컬럼 번역팀에서 번역한 내용입니다. 그렇기에, 일부 오역이나 오타가 존재할 수 있는 점 미리 양해를 구합니다. 원문에 대한 모든 저작권은 마이크로소프트에 있으며, 컬럼 내용과 관련한 질의 문답 역시 원문 사이트에 문의하시는 것을 추천드립니다.

Razor구문을 사용한 ASP.NET 웹 프로그래밍 소개

이번 장에서는 Razor구문을 사용해서 ASP.NET 웹 페이지를 개발하는 방법을 살펴봅니다. ASP.NET은 웹 서버에서 동적으로 웹 페이지를 구현하기 위한 MS의 기술입니다.

이번 컬럼에서는 다음과 같은 내용을 배우게 됩니다.

  • Razor구문으로 ASP.NET 웹 페이지 개발을 시작하기 위한 8가지 개발 팁.
  • 이번 컬럼을 이해하기 위해서 필요한 기본 프로그래밍 개념.
  • ASP.NET 서버 코드와 Razor구문.

8가지 개발 팁

이번 절에서는 Razor구문을 사용하여 ASP.NET 서버 코드를 작성하기 위해 꼭 필요한 몇 가지 팁들을 다룹니다.

주의 : Razor구문은 C#을 기반으로 하고 있고 이번 컬럼에서도 C#을 사용하고 있지만, Razor는 Visual Basic 언어도 지원하기에, 이 강좌에 있는 모든 내용은 Visual Basic 으로도 개발할 수 있습니다. 비주얼 베이직과 관련한 자세항 내용을 알고 싶다면 Visual Basic Language and Syntax를 참고하시기 바랍니다.

1. 페이지에서 @문자를 사용하는 방법

@문자는 인라인 표현식(inline expressions)과 코드 블럭의 시작을 알립니다.

<!-- 한 줄로 구성된 코드 블럭 -->
@{ var total = 7; }
@{ var myMessage = "Hello World"; }

<!-- 인라인 표현식 -->
<p>The value of your account is: @total </p>
<p>The value of myMessage is: @myMessage</p>
  
<!-- 여러 줄로 구성된 코드 블럭 -->
@{
    var greeting = "Welcome to our site!";
    var weekDay = DateTime.Now.DayOfWeek;
    var greetingMessage = greeting + " Today is: " + weekDay;
}
<p>The greeting is: @greetingMessage</p>

이 코드가 실행되면 웹 브라우저에서 다음과 같이 보여집니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573043/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-1_4.jpg

HTML 인코딩

위의 예제와 같이 @ 문자를 사용하여 페이지의 내용을 작성하면, ASP.NET이 페이지를 출력할 때 해당 내용에 대해 HTML 인코딩(Encoding)을 수행합니다. 이러한 인코딩 작업은 HTML 예약 문자들(<,>,&..등)을 HTML태그나 HTML엔터티(Entities)로 해석하는 것이 아니라 문자 그대로 출력되도록 합니다. HTML 인코딩을 하지 않으면, 서버 코드의 출력이 올바르게 표시되지 않거나 해당 페이지가 보안위험에 노출될 수 있습니다.

HTML 마크업(HTML markup)으로 출력해야 하는 경우(단락을 구분하기 위해 <p></p>를 쓰고 싶거나, 강조하기 위해 <em></em>을 사용하고 싶은 경우)라면 이번 장의 중간쯤에 있는 '코드 블럭에서 텍스트, HTML 마크업, 서버 코드를 조합하는 방법' 절을 참고하시면 됩니다.

2. 코드 블럭은 중괄호로 열고 닫습니다

코드 블럭은 한 줄 또는 여러 줄의 코드로 구성될 수 있고 중괄호로 열고 닫아야 합니다.

<!-- 한 줄로 구성된 코드 블럭 -->
@{ var theMonth = DateTime.Now.Month; }
<p>The numeric value of the current month: @theMonth</p>

<!-- 여러 줄로 구성된 코드 블럭 -->
@{
    var outsideTemp = 79;
    var weatherMessage = "Hello, it is " + outsideTemp + " degrees.";
}
<p>Today's weather: @weatherMessage</p>

코드의 결과는 브라우저에서 다음과 같이 보여집니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573055/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-2_4.jpg

3. 코드 블럭에서 줄을 끝낼 때는 세미콜론(;)을 사용합니다

코드 블럭에서 줄을 종료할 때는 반드시 세미콜론(;)을 써주어야 합니다. 인라인 표현식은 세미콜론으로 종료하지 않습니다.

<!-- 한 줄로 구성된 코드 블럭 -->
@{ var theMonth = DateTime.Now.Month; }

<!-- 여러 줄로 구성된 코드 블럭 -->
@{
    var outsideTemp = 79;
    var weatherMessage = "Hello, it is " + outsideTemp + " degrees.";
}

<!-- 인라인 표현식은 세미콜론으로 종료하지 않습니다 -->
<p>Today's weather: @weatherMessage</p>

4. 값을 저장하기 위해서는 변수를 사용합니다.

var 키워드를 통해 새로운 변수를 만들어서 문자열, 숫자, 날짜 등을 저장할 수 있습니다. 그리고 @ 문자를 사용하여 페이지에 변수 값을 바로 출력할 수 있습니다.

<!-- 문자열 저장 -->
@{ var welcomeMessage = "Welcome, new members!"; }
<p>@welcomeMessage</p>

<!-- 날짜 저장 -->
@{ var year = DateTime.Now.Year; }

<!-- 변수값 출력 -->
<p>Welcome to our new members who joined in @year!</p>


출처 : http://i1.asp.net/umbraco-beta-media/2573067/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-3_4.jpg

5. 문자열(literal string values)은 큰따옴표(")로 열고 닫아야 합니다

문자열(string)은 텍스트로 취급되는 일련의 문자들입니다. 문자열로 지정하기 위해서는 큰따옴표로 감싸주어야 합니다.

@{ var myString = "This is a string literal"; }

만약 문자열이 역 슬래시(\)나 큰따옴표를 포함하고 있다면, @ 연산자를 앞에 붙여 축자 문자열 리터럴(verbatim string literal)을 사용합니다(C#에서 \문자는 축자 문자열 리터럴을 사용하지 않는 경우 예약어로 인식됩니다).

역자 주 : '축자'라는 말의 사전적 의미는 '글자를 하나하나 따름'입니다. msdn에서 verbatim string literal을 축자 문자열 리터럴로 번역해놓았는데, 용어를 통일하는 것이 좋을 것 같아 본문에서도 동일한 용어를 사용했습니다. (참고 : http://msdn.microsoft.com/ko-kr/library/aa691090(VS.71).aspx)

<!-- 역 슬래시를 포함하는 문자열 -->
@{ var myFilePath = @"C:\MyFolder\"; }
<p>The path is: @myFilePath</p>

큰 따옴표를 문자열에 넣기 위해서는, 축자 문자열 리터럴을 사용하고 큰 따옴표를 두 번씩 입력해야 합니다.

<!-- 큰따옴표를 포함하는 문자열 -->
@{ var myQuote = @"The person said: ""Hello, today is Monday."""; }
<p>@myQuote</p>

결과는 브라우저에서 다음과 같이 보여집니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573079/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-4_4.jpg

주의 @ 문자는 ASP.NET 페이지에서 축자 문자열 리터럴 표시뿐만 아니라, 서버 코드를 구분하는데도 사용됩니다.

6. 서버 코드는 대소문자를 구분합니다

C#에서는 키워드(var, true, if 등)와 변수명의 대소문자를 구분합니다. 아래의 코드는 lastName과 LastName 두 개의 변수를 생성합니다.

@{
    var lastName = "Smith";
    var LastName = "Jones";
}

만약 var lastName = "Smith"; 이렇게 변수를 선언하고, 페이지에서 @LastName으로 참조하면 LastName이라는 변수가 없기 때문에 에러가 발생합니다.

주의 Visual Basic에서는 키워드와 변수의 대소문자를 구분하지 않습니다.

7. 서버 코드에서 객체를 사용하는 방법

객체(object)는 페이지, 텍스트 박스, 파일, 이미지, 웹 요청, 이메일 메세지, 데이터베이스 행(database row)과 같은 고객 레코드(a customer record) 등 프로그램 할 수 있는 어떤 것들을 나타냅니다. 객체들은 그것이 어떤 객체인지 나타내는 속성(property)들을 가지고 있습니다. 예를 들면, 텍스트 박스 객체는 Text, 요청(Request) 객체는 Url, 이메일 메세지는 From, 고객 객체는 FistName 등의 속성을 가지고 있습니다(객체에 속성이 하나씩 있는 건 아니고, 여러 개의 속성을 가질 수도 있습니다). 객체는 또한 어떤 기능을 실행할 수 있는 메서드(method)도 가질 수 있습니다. 예를 들면, 파일 객체는 Save, 이미지 객체는 Rotate, 이메일 객체는 Send 등의 메서드를 가지고 있습니다.

Request 객체는 전송된 폼 필드들의 값(텍스트 박스 등), 요청을 생성한 브라우저의 종류, 페이지의 URL, 사용자 식별 등의 정보를 제공하는 객체로 자주 사용됩니다. 다음 예제는 Request 객체 속성에 접근하는 방법과 해당 페이지의 절대 경로를 알려주는 MapPath 메서드를 호출하는 방법을 보여줍니다.

<table border="1">
<tr>
    <td>Requested URL</td>
    <td>Relative Path</td>
    <td>Full Path</td>
    <td>HTTP Request Type</td>
</tr>
<tr>
    <td>@Request.Url</td>
    <td>@Request.FilePath</td>
    <td>@Request.MapPath(Request.FilePath)</td>
    <td>@Request.RequestType</td>
</tr>
</table>

그 결과는 브라우저에서 다음과 같이 보여집니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573091/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-5_4.jpg

8. 선택적으로 동작하는 코드를 작성하는 방법

동적 웹 페이지의 핵심 기능은 조건에 따라 어떤 작업을 할지 결정할 수 있다는 점입니다. 이 기능을 구현하는 일반적인 방법은 if문을 사용하는 것입니다(선택적으로 else문을 함께 사용합니다).

@{
  var result = "";
  if(IsPost)
  {
      result = "This page was posted using the Submit button.";
  }
  else
  {
      result = "This was the first request for this page.";
  }
}

<!DOCTYPE html>
<html>
    <head>
        <title></title>
    </head>
<body>
<form method="POST" action="" >
  <input type="Submit" name="Submit" value="Submit"/>
  <p>@result</p>
</form>
</body>
</html>
    </body>
</html>

if(IsPost)는 if(IsPost == true)를 약식으로 표기한 것입니다. if 문으로 조건을 테스트하고, 코드 블럭을 반복하는 등의 다양한 작업 방법에 대해서는 이 강좌 뒤 쪽에서 설명하고 있습니다.

코드의 결과는 브라우저에서 다음과 같이 보여집니다.(Submit버튼을 클릭한 후)


출처 : http://i1.asp.net/umbraco-beta-media/2573103/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-6_4.jpg

HTTP GET과 POST 방식 그리고 IsPost속성

웹 페이지를 위해 사용되는 프로토콜인 HTTP는 서버로의 요청을 생성하는데 사용되는 매우 제한된 메서드들(동사, verb)만을 지원합니다. 가장 일반적인 두 가지 메서드는 페이지를 요청하기 위해 사용하는 GET, 페이지를 제출(submit)하기 위해 사용하는 POST입니다. 일반적으로 사용자가 페이지를 처음 요청할 때, 페이지는 GET방식으로 요청됩니다. 만약 사용자가 폼을 모두 채우고 제출 버튼을 클릭하면, 브라우저는 서버로 보낼 POST 방식의 요청을 생성합니다.

웹 프로그래밍에서, 페이지 요청이 GET으로 왔는지 POST로 왔는지에 대한 정보는 해당 페이지를 처리할 때 유용한 정보로 사용되는 경우가 많습니다. ASP.NET 웹 페이지에서는 IsPost 속성을 사용하여 페이지가 GET 또는 POST로 요청된 것을 확인할 수 있습니다. 페이지가 POST로 요청되었다면 IsPost속성은 true를 반환하고, 폼 안의 텍스트 박스 값을 구하는 등의 작업이 가능하게 됩니다. 앞으로 나오는 예제에서는 IsPost 값에 따라 페이지를 다르게 처리하는 여러 가지 방법을 배울 수 있습니다.

간단한 예제 코드

이번 예제는 페이지를 만드는 기본적인 프로그래밍 기술을 보여줍니다. 사용자로부터 두 개의 숫자를 받아 그 합을 출력하는 페이지를 만듭니다.

  1. 새 파일을 만들어 이름을 AddNumbers.cshtml로 저장합니다.
  2. AddNumbers.cshtml에 어떤 내용이 있다면 모두 지우고, 아래의 코드와 HTML 마크업을 복사해서 붙여 넣습니다.

    @{
        var total = 0;
        var totalMessage = "";
        if(IsPost) {
            // 사용자가 입력한 숫자를 저장합니다.
            var num1 = Request["text1"];
            var num2 = Request["text2"];

            // 문자열을 숫자로 변환해서 합계를 구합니다.
            total = num1.AsInt() + num2.AsInt();
            totalMessage = "Total = " + total;
        }
    }

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <title>Add Numbers</title>
        <meta charset="utf-8" />
        <style type="text/css">
          body {background-color: beige; font-family: Verdana, Arial;
                margin: 50px; }
          form {padding: 10px; border-style: solid; width: 250px;}
        </style>
      </head>
    <body>
      <p>Enter two whole numbers and then click <strong>Add</strong>.</p>
      <form action="" method="post">
        <p><label for="text1">First Number:</label>
          <input type="text" name="text1" />
        </p>
        <p><label for="text2">Second Number:</label>
          <input type="text" name="text2" />
        </p>
        <p><input type="submit" value="Add" /></p>
      </form>

      <p>@totalMessage</p>

    </body>
    </html>

    다음 사항을 유의하십시오.

    • @ 문자로 시작하는 첫 번째 코드 블럭은 페이지 아래쪽에 있는 totalMessage 변수보다 먼저 처리됩니다.
    • 페이지 상단의 코드 블럭은 중괄호({})로 감싸져 있습니다.
    • 상단 코드 블럭의 모든 줄은 세미콜론(;)으로 종료되었습니다.
    • total, num1, num2 그리고 totalMessage 변수는 각각의 숫자와 문자열을 저장합니다.
    • 리터럴 문자열(literal string)은 큰따옴표(")로 둘러싸여 totalMessage 변수에 저장되었습니다.
    • 대소문자를 구분하기 때문에, 페이지 하단에서 totalMessage 변수를 사용할 경우 상단에 선언된 변수명을 정확하게 써주어야 합니다.
    • num1.AsInt() + num2.AsInt() 표현식은 객체와 메서드를 어떻게 사용하는지 보여줍니다. AsInt 메서드는 문자열을 숫자로 변환하여, 숫자연산이 가능하게 합니다.
    • <form> 태그는 method="post" 속성을 가지고 있습니다. 따라서 사용자가 Add 버튼을 클릭하면, 페이지는 HTTP POST 방식으로 서버에 전송됩니다. 페이지가 제출되면, if(IsPost)는 true를 반환하여 조건문 블럭의 코드가 실행되고, 숫자들의 합계가 출력됩니다.

  3. 페이지를 저장하고 브라우저에서 실행합니다(실행하기 전에 해당 페이지가 선택되었는지 확인합니다). 두 숫자를 입력하고 Add 버튼을 클릭하십시오.


    출처 : http://i1.asp.net/umbraco-beta-media/2573115/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-7_4.jpg

기본 프로그래밍 개념

위의 예제들에서 본 것처럼 ASP.NET 웹 페이지와 Razor 구문에 대한 개발 경험이 없어도 빠르게 정교한 동적 웹 페이지를 만들 수 있고, 이는 많은 양의 코드를 필요로 하지도 않습니다.

이번 장은 ASP.NET 웹 개발의 개요를 설명합니다. 완벽한 설명은 아니지만, 자주 사용되는 프로그래밍 개념을 빠르게 훑어볼 것입니다. 이 강좌의 나머지 부분을 이해하기에 충분한 내용입니다.

먼저 기술적인 배경입니다.

Razor 구문, 서버 코드 그리고 ASP.NET

Razor 구문은 웹 페이지에 서버 코드를 끼워 넣기 위해 만들어진 간단한 프로그래밍 구문입니다. Razor 구문을 사용하는 웹 페이지는 클라이언트 컨텐츠와 서버 코드로 구성됩니다. 클라이언트 컨텐츠는 HTML마크업, CSS, 자바스크립트, 일반 텍스트 등 웹 페이지에서 일반적으로 사용하는 것들입니다.

Razor 구문은 이 클라이언트 컨텐츠에 서버 코드를 끼워 넣는 방법입니다. 페이지에 서버 코드가 있으면, 서버는 브라우저에 페이지를 전송하기 전에 서버 코드를 먼저 실행합니다. 이때 서버 코드는 데이터베이스에 접속하는 등 클라이언트 컨텐츠에서 하기 어려운 복잡한 작업을 수행할 수 있습니다. 가장 중요한 점은, 서버 코드가 클라이언트 컨텐츠를 동적으로 생성할 수 있다는 것입니다. 요청 받는 시점에 HTML 마크업이나 다른 컨텐츠들을 즉시 생성해서 정적 HTML 컨텐츠와 함께 전송할 수 있습니다. 브라우저의 입장에서는 서버 코드에 의해 생성된 클라이언트 컨텐츠나 그 밖에 다른 클라이언트 컨텐츠나 다를 것이 없습니다. 앞의 예제에서 본 것과 같이, 클라이언트 컨텐츠에 서버 코드를 넣는 것은 매우 간단합니다.

Razor 구문을 사용하는 ASP.NET 웹 페이지는 파일 확장자가 .cshtml 또는 .vbhtml입니다. 서버는 이 확장자들을 인식하여 Razor구문 코드를 실행한 후, 브라우저로 페이지를 전송합니다.

ASP.NET은 어디서 동작하나요?

Razor 구문은 ASP.NET을 기반으로 하고, ASP.NET은 .NET Framework를 기반으로 합니다. .NET Framework는 거의 모든 종류의 프로그램을 개발할 수 있도록 만들어진 크고 포괄적인 개발 프레임워크입니다. ASP.NET은 웹 응용 프로그램을 만들기 위해 특별히 설계된 .NET Framework의 한 부분입니다. 개발자들은 세계에서 가장 크고, 트래픽(traffic)이 많은 웹사이트를 개발하는데 ASP.NET을 사용했습니다(URL에 .aspx 확장자를 가진 웹사이트는 ASP.NET으로 개발된 사이트입니다).

Razor 구문은 문법이 간략해서 초급 개발자는 배우기 쉽고 전문가는 더 생산적으로 작업할 수 있습니다. 또한 사용하기 쉬울 뿐만 아니라 ASP.NET 그리고 .NET Framework의 기능을 활용할 수 있습니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573127/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-8_4.jpg

클래스와 인스턴스

ASP.NET 서버 코드는 클래스에 기반을 둔 객체를 사용합니다. 클래스는 객체에 대한 정의 또는 템플릿입니다. 예를 들어, 응용 프로그램은 customer 객체에 필요한 속성과 메서드를 정의하는 Customer 클래스를 포함할 수 있습니다.

응용 프로그램은 고객 정보를 가지고 작업할 필요가 있을 때 customer 객체의 인스턴스(instance)를 만듭니다. 각각의 customer는 Customer 클래스의 개별 인스턴스입니다. 모든 인스턴스는 동일한 속성과 메서드를 지원하지만, 각각의 customer 객체가 유일하기 때문에 일반적으로 개별 인스턴스의 속성값은 인스턴스 별로 다릅니다. 어떤 customer 객체의 LastName 속성값이 "Smith"라면, 다른 customer 객체의 LastName 속성값은 "Jones"가 될 수 있습니다.

비슷한 원리로, 각각의 웹 페이지는 Page 클래스의 인스턴스인 Page 객체입니다. 페이지에 있는 버튼은 Button 클래스의 인스턴스인 Button 객체고, 다른 것들도 마찬가지입니다. 각각의 인스턴스는 개별적인 특성이 있지만, 모두 자신을 정의한 클래스에 기반을 두고 있습니다.

언어와 구문

이미 예제를 통해 ASP.NET 웹 페이지를 만들고, HTML 마크업에 서버 코드를 끼워 넣는 방법을 배웠습니다. 이제 프로그래밍 관점에서 Razor 구문을 이용해 서버 코드를 작성하는 방법을 살펴보겠습니다.

C, C++, Visual Basic 또는 JavaScript를 사용해본 경험이 있다면 더 쉽게 배우실 수 있을 겁니다. HTML 마크업에 서버 코드를 끼워 넣는 일은 익숙해지실 필요가 있습니다.

기본 문법

코드 블럭에서 텍스트, HTML 마크업, 서버 코드를 조합하는 방법

서버 코드 블럭에서 페이지에 텍스트나 HTML 마크업을 출력하는 일은 빈번하게 일어납니다. 서버 코드 블럭이 보이는 그대로 렌더링 되어야 하는 텍스트를 포함하고 있는 경우, ASP.NET이 이를 구분할 수 있어야 합니다. 여기에는 몇 가지 방법이 있습니다.

  • 텍스트를 <p></p>나 <em></em> 같은 HTML 요소(element)로 둘러쌉니다.

    @if(IsPost) {
        // 이 줄은 모든 컨텐츠를 짝이 있는 <p> 태그로 감싸주었습니다.
        <p>Hello, the time is @DateTime.Now and this page is a postback!</p>
    } else {
        // 모든 컨텐츠를 짝이 있는 태그로 감싸고, 서버 코드를 뒤에 넣었습니다.
      <p>Hello <em>stranger</em>, today is: <br /> </p>@DateTime.Now
    }

    HTML 요소는 텍스트, 추가적인 HTML요소 그리고 서버 코드 표현식(server-code expression)을 포함할 수 있습니다. ASP.NET이 브라우저에 전송하기 위한 내용을 렌더링 할 때 HTML 태그를 만나면, 태그 안에 있는 요소와 내용은 있는 그대로 반영합니다(그리고 서버 코드 표현식을 처리해서 반영합니다).

  • @: 연산자나 <text> 요소를 사용합니다. @: 연산자는 한 줄의 일반 텍스트(plain text)를 출력할 때나, <br />처럼 짝이 없는 HTML 태그를 출력할 때 사용할 수 있습니다. 여러 줄에 적용하고 싶을 때는 <text></text>태그를 사용하면 됩니다. 이 옵션(option)들은 출력의 일부분을 HTML 요소로 출력하고 싶지 않을 때 유용합니다.

    @if(IsPost) {
        // 일반 텍스트, 짝이 없는 HTML 태그, 서버코드가 함께 쓰여진 경우
        @: The time is: <br /> @DateTime.Now
        // 서버코드, 일반 텍스트, 짝이 있는 HTML 태그 등이 함께 쓰여진 경우
        @DateTime.Now @:is the <em>current</em> time.
    }

    여러 줄에 적용하려고 할 때, 앞서 언급된 <text> 태그를 사용하는 방법 외에도, 매 줄마다 @: 연산자를 써주는 방법도 있습니다. @: 연산자와 <text> 태그는 ASP.NET이 텍스트 컨텐츠를 인식하는데 사용하고 페이지에 출력하지는 않습니다.

    역자주: 코드 블럭 안에서 그냥 <text> 태그를 사용하면 서버 코드로 인식되어 브라우저에 전송되지 않지만, @: 연산자를 사용한 줄에 <text> 태그를 사용하면 HTML 마크업으로 인식되어 브라우저에 전송됩니다. <text> 태그 안에 <text> 태그를 중첩해서 사용한 경우도 마찬가지 입니다. 코드 블럭 밖에서 <text> 태그를 사용한 경우는 당연히 HTML 마크업으로 인식되어 브라우저에 전송됩니다.

    @if(IsPost) {
        // 이전 예제와 동일한 내용을 <text> 태그를 사용해서 구현했습니다.
       <text>
    The time is: <br /> @DateTime.Now
    @DateTime.Now is the <em>current</em> time.
    </text>
    }
    @{
    var minTemp = 75;

    <text>It is the month of @DateTime.Now.ToString("MMMM"), and
    it's a <em>great</em> day! <br /><p>You can go swimming if it's at
    least @minTemp degrees. </p></text>
    }

    첫 번째 코드 블럭은 <text> 태그를 사용하여 이전 예제를 구현했습니다. 두 번째 코드 블럭은 <text> 태그를 일반 텍스트, 짝이 없는 HTML 태그, 짝이 있는 HTML요소로 감싼 텍스트, 서버 코드가 섞여 있는 3줄의 컨텐츠에 적용했습니다. @: 연산자를 세 번 사용해서 동일한 작업을 할 수 있습니다.

    주의 @: 연산자와 <text></text> 요소가 사용된 컨텐츠는 ASP.NET이 HTML 인코딩을 수행하지 않습니다(앞에서 언급되었지만 ASP.NET은 서버 코드 표현식과 @로 시작하는 서버 코드 블럭을 출력할 때 HTML 인코딩 처리를 합니다. 하지만 @: 연산자와 <text></text> 요소가 사용된 경우는 예외입니다).

공백

코드에서 불필요한 공백은 아무 영향도 없습니다.

@{ var lastName =    "Smith"; }

줄바꿈도 아무런 영향을 미치지 않기 때문에, 가독성을 위해 줄바꿈을 사용할 수 있습니다. 아래의 두 코드 블럭은 동일한 코드로 볼 수 있습니다.

@{ var theName =
"Smith"; }

@{
    var
    personName
    =
    "Smith"
    ;
}

하지만 문자열 중간에 줄바꿈을 할 수는 없습니다. 다음 예제는 에러를 발생시킵니다.

@{ var test = "This is a long
    string"; } // 동작하지 않습니다

여러 줄의 긴 문자열을 만들기 위해서는 두 가지 방법이 있습니다. 우선, + 연산자를 사용할 수 있고, 이와 관련된 예제는 이 장 뒤쪽에 있습니다. 또 앞쪽의 예제에서 보았듯이, @ 문자를 사용해 축자 문자열 리터럴를 만드는 방법도 있습니다. 다음 예제와 같이 축자 문자열 리터럴에 줄바꿈을 사용할 수 있습니다.

@{ var longString = @"This is a
    long
    string";
}

주석 코드와 HTML 주석

주석으로 자신이나 다른 사람에게 메모를 남길 수 있습니다. 또 당분간 남겨두었으면 하는 실행되지 않는 코드 블럭을 만들 수도 있습니다.

Razor 코드를 위한 주석 구문과 HTML을 위한 주석 구문은 다릅니다. Rozor 코드의 주석은 브라우저로 전송되기 전에 제거됩니다. 따라서 개발자가 소스코드를 편집할 때는 볼 수 있지만, 웹 페이지 사용자는 볼 수 없습니다(브라우저의 소스코드 보기 기능으로도 볼 수 없습니다).

Razor 코드의 주석은 @*으로 시작해서 *@으로 끝냅니다. 한 줄 또는 여러 줄에 사용할 수 있습니다.

@*A one-line code comment. *@

@*
    This is a multiline code comment.
    It can continue for any number of lines.
*@

코드 블럭 안에서도 주석을 사용할 수 있습니다.

@{
    @* This is a comment. *@
    var theVar = 17;
}

다음과 같이 주석만 있는 코드 블럭을 만들 수도 있습니다.

@{
    @* This is a comment. *@
    @* var theVar = 17;  *@
}

코드 블럭 안에서는 C#과 같은 프로그래밍 언어의 주석 구문도 사용할 수 있습니다.

@{
    // C#의 주석구문을 사용한 한 줄의 주석입니다.
    var myVar = 17;
    
    /* C#의 주석구문을 사용한
       여러 줄의 주석입니다. */
}

C#의 주석은 한 줄인 경우 //로 시작하면 되고, 여러 줄인 경우 /*로 시작해서 */로 끝냅니다(Razor 구문의 주석과 마찬가지로 C#의 주석도 브라우저로 전송하기 전에 제거됩니다).

반면, HTML 마크업은 HTML 주석(<!-- -->)을 사용하면 됩니다.

<!-- 이 줄은 주석입니다. -->

HTML 주석은 <!--로 시작해서 -->로 끝냅니다. HTML 주석은 텍스트 뿐만 아니라 HTML 태그도 주석으로 처리할 수 있습니다. HTML 주석은 주석 안에 있는 HTML 태그와 텍스트가 페이지에 보여지지 않게 합니다.

<!-- <p>This is my paragraph.</p>  -->

Razor 코드 주석과는 달리 HTML 주석은 브라우저의 소스 보기를 통해 사용자가 주석을 볼 수 있습니다.

변수

변수는 데이터를 저장하는데 사용할 수 있는 이름이 붙여진 객체입니다. 변수 명은 원하는 대로 줄 수 있지만, 알파벳 문자로 시작해야 하고 공백이나 예약문자를 포함할 수 없습니다.

변수와 데이터 타입

변수는 저장된 데이터의 종류를 나타내는 특정 데이터 형식을 가질 수 있습니다. 문자열("Hello world" 같은)을 저장할 수 있는 sring, 정수(3이나 79 같은)를 저장할 수 있는 int, 다양한 양식(4/12/2010, March 2009 등)의 날짜를 저장할 수 있는 DateTime 등의 형식이 있고 이 외에도 사용할 수 있는 데이터 타입이 많이 있습니다.

하지만, 보통은 지정된 데이터 형식을 사용하지 않아도 됩니다. 대부분의 경우, ASP.NET은 변수에 저장되는 값을 통해 변수의 형식을 알아낼 수 있습니다(물론, 때때로는 변수의 형식을 지정해야 하는 경우도 있습니다).

변수를 선언할 때 형식을 지정하지 않는 경우에는 var 키워드를 사용하고, 형식을 지정하는 경우에는 형식명을 사용합니다.

@{
  // 문자열을 변수에 할당합니다.
  var greeting = "Welcome!";

  // 숫자를 변수에 할당합니다.
  var theCount = 3;

  // 수식을 통해 변수에 값을 할당합니다.
  var monthlyTotal = theCount + 5;

  // 날짜를 변수에 할당합니다.
  var today = DateTime.Today;

  // 현재 페이지의 URL을 변수에 할당합니다.
  var myPath = this.Request.Url;

  // 명시적인 데이터 형식으로 변수를 선언합니다.
  string name = "Joe";
  int count = 5;
  DateTime tomorrow = DateTime.Now.AddDays(1);
}

다음 예제는 웹 페이지에서 변수를 사용하는 일반적인 방법을 몇 가지 보여줍니다.

@{
  // HTML 마크업에 변수값을 사용합니다.
  <p>@greeting, friends!</p>
  
  // 인라인 표현식의 부분으로 변수를 사용합니다.
  <p>The predicted annual total is: @( monthlyTotal * 12)</p>
  
  // 변수를 사용하여 페이지 URL을 보여줍니다.
  <p>The URL to this page is: @myPath</p>
}

결과는 브라우저에서 다음과 같이 보여집니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573139/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-9_4.jpg

데이터 형식의 변환과 테스트

ASP.NET은 보통 자동으로 데이터 형식을 결정하지만, 그럴 수 없는 경우도 있습니다. 따라서 명시적인 변환을 해서 ASP.NET을 도와줘야 하는 경우가 있습니다. 꼭 데이터를 변환할 필요가 없는 경우에도, 작업 중인 데이터의 형식을 확인하기 위해 데이터 변환이 필요한 경우가 종종 있습니다.

보통 string을 int, DateTime 등의 형식으로 변환해야 하는 경우가 많습니다. 다음 예제는 string을 int로 변환할 필요가 있는 일반적인 예를 보여줍니다.

@{
  var total = 0;

  if(IsPost) {
    // 사용자가 입력한 숫자를 저장합니다.
    var num1 = Request["text1"];
    var num2 = Request["text2"];
    
    // 덧셈 연산으로 합계를 구하기 위해 문자열을 정수로 변환합니다.
    total = num1.AsInt() + num2.AsInt();
  }
}

기본적으로, 사용자의 입력은 문자열로 생각해야 합니다. 사용자의 숫자 입력을 유도해서 사용자가 숫자를 입력했더라도, 사용자의 입력이 제출되어 서버에서 읽혀질 때 그 데이터의 형식은 문자열입니다. ASP.NET은 문자열 형식으로 사칙연산을 할 수 없기 때문에, 해당 데이터로 덧셈을 해야 한다면 숫자로 변환해야 합니다. ASP.NET은 두 문자열에 덧셈 연산을 할 수 없기 때문에, 문자열 형식을 가진 변수들을 숫자로 변환하지 않고 덧셈 연산을 시도하면 잘못된 결과값을 얻게 됩니다(덧셈이 아닌 문자열 연결이 수행되거나, 경우에 따라 오류가 발생할 수 있습니다. 결과값을 할당 받는 변수가 정수로 선언된 경우 등)

string 형식을 int 형식으로 변환할 때 암묵적인 변환은 지원되지 않기 때문에, 반드시 명시적으로 변환해주어야 합니다.

AsInt 메서드를 사용해서 변수의 값을 정수로 변환할 수 있습니다. 변환이 성공한다면 숫자로서 연산이 가능하게 됩니다.

다음 표는 변수를 변환하고 테스트하기 위한 공통 메서드 목록입니다.

메서드

설명

예제

AsInt(),
IsInt()

숫자로만 구성된 문자열("539"처럼)을 정수로 변환합니다.

var myIntNumber = 0;
var myStringNum = "539";
if (myStringNum.IsInt() == true)
{
    myIntNumber = myStringNum.AsInt();
}

AsBool(),
IsBool()

"true" 나 "false" 같은 문자열을 불린(Boolean) 형식으로 변환합니다.

var myStringBool = "True";
var myVar = myStringBool.AsBool();

AsFloat(),
IsFloat()

"1.3"이나 "7.439"처럼 소수를 값으로 가진 문자열을 부동 소수점 수(floating-point number)로 변환합니다.

var myStringFloat = "41.432895";
var myFloatNum = myStringFloat.AsFloat();

AsDecimal(),
IsDecimal()

"1.3"이나 "7.439"처럼 소수를 값으로 가진 문자열을 소수(decimal number)로 변환합니다. (ASP.NET에서 소수는 부동 소수점 수보다 더 정밀합니다.)

var myStringDec = "10317.425";
var myDecNum = myStringDec.AsDecimal();

AsDateTime(),
IsDateTime()

일자와 시간을 값으로 갖는 문자열을 ASP.NET의 DateTime 형식으로 변환합니다.

var myDateString = "12/27/2010";
var newDate = myDateString.AsDateTime();

ToString()

다른 형식의 데이터들을 문자열로 변환합니다.

int num1 = 17;
int num2 = 76;
// myString은 1776으로 설정됩니다
string myString = num1.ToString() +
    num2.ToString();

연산자

연산자는 ASP.NET에게 어떤 연산을 수행해야 하는지 알려주는 키워드와 문자입니다. C#은 많은 연산자들을 지원하지만, 몇 가지만 알고 있어도 개발을 시작할 수 있습니다(Razor 구문은 C#에 기반을 두고 있습니다). 다음 표는 일반적으로 사용되는 연산자들을 요약해놓은 표입니다.

Operator

Description

Examples

+
-
*
/

수식에 사용되는 숫자 연산자(Math operators)

@(5 + 13)
@{ var netWorth = 150000; }
@{ var newTotal = netWorth * 2; }
@(newTotal / 2)
=

할당. 오른쪽 구문의 값을 왼쪽 객체에 할당합니다.

var age = 17;
==

일치(Equality). 양쪽의 값이 동일하면 true를 반환합니다( = 연산자와 == 연산자의 차이를 주의하세요).

var myNum = 15;
if (myNum == 15)
{
    // 어떤 작업을 수행한다
}
!=

불일치(Inequality). 양쪽의 값이 일치하지 않으면 true를 반환합니다.

var myNum = 15;
if (myNum != 15)
{
    // 어떤 작업을 수행한다
}

<
>
<=
>=

더 작은, 더 큰, 작거나 같은, 크거나 같은.
if (2 < 3)
{
    // 어떤 작업을 수행한다
}
var currentCount = 12;
if (currentCount >= 12)
{
    // 어떤 작업을 수행한다
}

+

연결, 문자열을 연결할 때 사용합니다. ASP.NET은 표현식(expression)의 데이터 형식으로 덧셈 연산자와 연결 연산자를 구분합니다.

// 출력 결과는 "abcdef".
@("abc" + "def")

+=

-=

증가, 감소 연산자는 연산자 우측의 값으로 좌측 변수의 값을 증가시키거나 감소시킵니다.

int theCount = 0;
theCount += 1; // count에 1을 더합니다

.

마침표(.)는 객체와 그 속성, 메서드를 식별하는데 사용합니다.

var myUrl = Request.Url;
var count = Request["Count"].AsInt();

()

괄호는 표현식을 묶을 때나 메서드에 매개변수를 입력할 때 사용합니다.

@(3 + 7)
@Request.MapPath(Request.FilePath);

[]

대괄호([])는 배열이나 컬렉션의 값에 접근할 때 사용합니다.

var income = Request["AnnualIncome"];

!

느낌표(!)는 true 값을 false로 뒤집거나 false값을 true로 뒤집습니다. 주로 false인 경우 어떤 처리를 하고 싶을 때 약식표현으로 많이 사용합니다.

bool taskCompleted = false;
// Processing.
if (!taskCompleted)
{
    // Continue processing
}

&&

||

논리 AND, OR 입니다. 조건들을 연결할 때 사용합니다.

bool myTaskCompleted = false;
int totalCount = 0;
// Processing.
if (!myTaskCompleted && totalCount < 12)
{
    // Continue processing.
}

코드에서 파일과 폴더 경로 사용하는 방법

파일과 폴더 경로는 코드에서 빈번하게 사용됩니다. 아래 예제는 웹사이트에서 실제 폴더 구조를 사용하는 예들입니다.

C:\WebSites\MyWebSite
default.cshtml
datafile.txt
\images
Logo.jpg
\styles
Styles.css

URL과 경로에 대한 핵심적인 내용은 다음과 같습니다.

  • URL은 도메인명(http://www.example.com) 이나 서버명(http://localhost, http://mycomputer)으로 시작합니다.
  • URL은 서버(호스트 컴퓨터)의 실제 경로에 대응됩니다. 예를 들면, URL http://myserver는 서버의 C:\websites\mywebsite 폴더에 대응될 수 있습니다.
  • 가상 경로는 코드에서 전체 경로 대신 사용할 수 있는 약칭입니다. 가상 경로는 도메인이나 서버명 뒤에 나오는 URL의 일부분으로 사용됩니다. 가상 경로를 사용하면 경로를 수정하지 않고 다른 도메인이나 서버로 코드를 옮길 수 있습니다.

다음은 차이점을 이해할 수 있도록 도와주는 예제입니다:

Complete URL http://mycompanyserver/humanresources/CompanyPolicy.htm
Server name mycompanyserver
Virtual path /humanresources/CompanyPolicy.htm
Physical path C:\mywebsites\humanresources\CompanyPolicy.htm

C: 드라이브의 루트가 \인 것처럼 가상 루트는 /입니다(가상 폴더 경로는 항상 /로 시작합니다). 폴더의 가상경로는 실제 폴더명과 일치하지 않아도 되고, 별칭을 사용할 수 있습니다(실제 운영환경에서 가상 경로가 서버의 실제 경로와 일치하는 경우는 별로 없습니다).

파일, 폴더 관련 코드를 작성할 때, 어떤 대상을 가지고 작업하느냐에 따라 어떤 경우는 실제 경로를, 어떤 경우는 가상의 경로를 참조할 필요가 있습니다. ASP.NET은 코드에서 파일과 폴더 경로 관련 작업을 할 수 있도록 ~연산자, Server.MapPath 메서드, Href 메서드를 제공합니다.

~ 연산자는 가상경로의 루트를 의미합니다.

서버 코드에서 가상 경로의 루트를 가리킬 때 ~ 연산자를 사용합니다. 이 연산자는 코드에서 경로를 수정하지 않고 웹사이트를 다른 폴더나 위치로 옮기는 경우에 유용합니다.

@{
    var myImagesFolder = "~/images";
    var myStyleSheet = "~/styles/StyleSheet.css";
}

Server.MapPath 메서드는 가상경로를 실제 경로로 변환합니다.

Server.MapPath 메서드는 '/default.cshtml' 같은 가상 경로를 'C:\WebSites\MyWebSiteFolder\default.cshtml' 같은 실제 경로로 변환합니다. 웹 서버에 텍스트 파일을 쓰거나 읽을 때처럼 실제 경로가 필요할 때 이 메서드를 사용합니다(일반적으로 웹 호스팅 업체의 서버를 이용하는 경우, 실제 경로를 알지 못하는 경우가 많습니다). Server.MapPath 메서드에 파일이나 폴더의 가상 경로를 매개변수로 넘기면, 실제 경로를 반환합니다.

@{
    var dataFilePath = "~/dataFile.txt";
}
<!-- C:\Websites\MyWebSite\datafile.txt 처럼 실제 경로를 보여주게 됩니다 -->
<p>@Server.MapPath(dataFilePath)</p>

Href 메서드는 사이트 리소스의 경로를 생성합니다.

WebPage 객체의 Href 메서드는 서버 코드의 경로(~ 연산자를 가질 수도 있음)를 브라우저가 인식할 수 있는 경로로 변환합니다(브라우저는 ASP.NET에서 사용하는 ~ 연산자를 해석할 수 없습니다). 이미지 파일, 다른 웹 페이지, CSS 파일..등의 리소스 경로를 지정할 때 Href 메서드를 사용할 수 있습니다. 예를 들면 <img>, <link>, <a> 요소의 속성값을 생성하는 용도로 사용할 수 있습니다.

@{
    var myImagesFolder = "~/images";
    var myStyleSheet = "~/styles/StyleSheet.css";
}

<!-- 이 코드는 img요소의 src속성을 "../images/Logo.jpg"로 설정합니다 -->
<img src="@Href(myImagesFolder)/Logo.jpg" />

<!-- 이 코드는 위의 코드와 동일하지만 "~/images"를 직접 입력했습니다 -->
<img src="@Href("~/images")/Logo.jpg" />

<!-- 이 코드는 CSS 파일에 대한 링크를 생성합니다 -->
<link rel="stylesheet" type="text/css" href="@Href(myStyleSheet)" />

조건문과 반복문

ASP.NET 서버 코드에서는 특정 조건을 만족할 때 코드를 실행하는 조건문과, 지정된 숫자만큼 코드를 반복 실행하는 반복문을 사용할 수 있습니다.

조건문

if 문은 결과값이 true 또는 false인 조건식을 테스트하여, 결과값이 true인 경우 지정된 코드를 실행합니다.

@{
  var showToday = true;
  if(showToday)
  {
    @DateTime.Today;
  }
}

if 키워드는 조건문을 시작합니다. 실제 테스트는 괄호 안의 조건식에서 이루어지고, true 또는 false를 반환합니다. 테스트 결과가 true인 경우 중괄호({}) 안의 코드가 실행됩니다. if문은 else문를 추가해서 테스트가 false를 반환한 경우에 특정 코드가 실행되도록 할 수 있습니다.

@{
  var showToday = false;
  if(showToday)
  {
    @DateTime.Today;
  }
  else
  {
    <text>Sorry!</text>
  }
}

else if 블럭을 사용해서 여러 개의 조건문을 추가할 수 있습니다.

@{
  var theBalance = 4.99;
  if(theBalance == 0)
  {
    <p>You have a zero balance.</p>
  }
  else if (theBalance  > 0 && theBalance <= 5)
  {
    <p>Your balance of $@theBalance is very low.</p>
  }
  else
  {
    <p>Your balance is: $@theBalance</p>
  }
}

위의 예제에서 첫 번째 if 문이 조건을 만족하지 못하면, else if문을 체크합니다. else if 문이 조건을 만족하면 else if 블럭의 코드가 실행됩니다. 모든 조건문이 조건을 만족하지 못하면, else 블럭의 코드가 실행됩니다. else if 블럭은 얼마든지 추가할 수 있고, 모든 조건에 해당되지 않는 경우를 위해 끝에 else 블럭을 추가할 수 있습니다.

테스트할 조건이 많은 경우 switch 블럭을 사용합니다.

@{
  var weekday = "Wednesday";
  var greeting = "";

  switch(weekday)
  {
    case "Monday":
      greeting = "Ok, it's a marvelous Monday";
      break;
    case "Tuesday":
      greeting = "It's a tremendous Tuesday";
      break;
    case "Wednesday":
      greeting = "Wild Wednesday is here!";
      break;
    default:
      greeting = "It's some other day, oh well.";
      break;
  }

  <p>Since it is @weekday, the message for today is: @greeting</p>
}

위 예제의 weekday 변수처럼 테스트할 값은 괄호 안에 넣습니다. 각각의 테스트를 수행하는 case문은 콜론(:)으로 마칩니다. 테스트 값이 case문의 값과 일치하는 경우, case 블럭의 코드가 실행됩니다. 각각의 case문은 break문으로 마칩니다. (break문을 넣지 않으면, 실행 시에 에러가 발생합니다. switch문에는 모든 case문을 만족하지 못하는 경우 실행되는 default문을 넣는 것이 일반적입니다.

이번 예제와 바로 전 예제는 브라우저에 다음과 같이 출력됩니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573151/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-10_4.jpg

반복문

같은 코드를 반복적으로 실행해야 하는 경우는 자주 있습니다. 이런 경우는 보통 반복문을 사용합니다. 일반적인 예로 데이터 컬렉션에 있는 각각의 아이템(item)에 대해 동일한 코드를 실행하는 경우를 들 수 있습니다. 만약 몇 번을 반복해야 하는지 알고 있다면 for문을 사용할 수 있습니다. 이런 종류의 반복은 특별히 숫자를 순차적으로 높이거나 낮출 때 유용합니다.

@for(var i = 10; i < 21; i++)
{
    <p>Item #: @i</p>
}

for 키워드로 시작하는 반복문은 괄호 안에 반복을 위한 초기 변수값 설정, 반복 조건문, 변수값 증감을 위한 세 가지 코드가 들어가고 각 코드는 세미콜론(;)으로 마칩니다.

  • 괄호 안에 첫 번째 코드(var i=10;)는 카운터 변수 i를 선언하고 초기값을 10으로 설정합니다. 카운터 변수명은 i가 아니어도 상관없고, 원하는 이름을 사용할 수 있습니다. 반복문이 실행되면, 카운터 변수는 자동으로 증가됩니다.
  • 두 번째 코드(i < 21;)는 반복에 대한 조건을 설정합니다. 이 예제에서는 카운터 변수가 20까지 증가되도록 했습니다(카운터 변수가 21보다 작으면 계속 실행됩니다).
  • 세 번째 코드(i++)는 증가 연산자를 사용해서 반복문이 실행될 때마다 카운터 변수가 1씩 증가되도록 했습니다.

중괄호({})에 있는 코드는 반복문이 반복될 때마다 실행됩니다. 반복문이 실행될 때마다 <p> 요소로 인해 새로운 단락이 생성되고, 단락에는 카운터 변수 i의 값이 출력됩니다. 이 페이지를 실행하면, 10 ~ 20까지 카운터 변수의 값이 포함된 11줄의 텍스트가 출력됩니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573163/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-11_4.jpg

컬렉션이나 배열로 작업하는 경우는 foreach문을 사용하면 됩니다. 컬렉션은 유사한 객체의 그룹이고, foreach문은 컬렉션의 각 아이템에 대한 작업을 수행할 수 있습니다. foreach문은 컬렉션 작업에 편리한 반복문으로 for문과 달리 카운터 변수를 증가시키거나 제한값을 설정할 필요가 없습니다. foreach문의 코드는 단순히 컬렉션이 끝날 때까지 반복됩니다.

다음 예제는 웹 서버의 정보를 담고 있는 Request.ServerVariables 컬렉션의 아이템들을 반환합니다. foreach문으로 아이템명의 목록을 <li>요소를 사용하여 출력합니다.

<ul>
@foreach (var myItem in Request.ServerVariables)
{
    <li>@myItem</li>
}
</ul>

foreach 키워드 뒤에 괄호를 쓰고, 그 안에 컬렉션의 한 아이템을 나타내는 변수를 선언(이 예제에서는 var item)하고, in 키워드를 쓰고, 해당 컬렉션을 써줍니다. foreach 루프의 몸체에서는 앞서 괄호 안에서 선언한 변수를 통해 현재 아이템에 접근할 수 있습니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573175/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-12_4.jpg

보다 범용적으로는 while문을 사용합니다.

@{
    var countNum = 0;
    while (countNum < 50)
    {
        countNum += 1;
        <p>Line #@countNum: </p>
    }
}

while문은 while 키워드로 시작하고 이어서 괄호를 써줍니다. 그리고 괄호 안에 얼마나 반복할 것인지를 지정하는 조건을 넣습니다(이번 예제에서는 countNum이 50보다 작으면 계속 반복됩니다). 그리고, 이어서 반복할 블럭을 써줍니다. 일반적으로 블럭 안에서 카운팅하기 위한 변수나 객체를 증가시키거나 감소시킵니다. 이번 예제에서는 블럭이 실행될 때마다 += 연산자로 countNum 변수를 1씩 증가시킵니다(카운터 변수를 감소시킬 때는 -= 연산자를 사용할 수 있습니다).

객체와 컬렉션

웹 페이지 자신을 포함해서 ASP.NET 웹사이트의 거의 모든 것이 객체입니다. 이 섹션에서는 자주 사용하는 몇몇 중요한 객체에 대해 알아봅니다.

Page 객체

ASP.NET의 가장 기본적인 객체는 Page입니다. 그렇기에, 어떤 객체를 지정하지 않아도 Page 객체의 속성에 바로 접근할 수 있습니다. 다음 코드는 Page의 Request 객체를 사용해서 페이지의 파일 경로를 얻습니다.

@{
    var path = Request.FilePath;
}

현재 page 객체(current page object)의 속성과 메서드를 참조한다는 것을 확실하게 하기 위해, page 객체를 나타내는 this 키워드를 선택적으로 사용할 수 있습니다. 다음 예제는 이전 예제에 this 키워드를 추가한 것입니다.

@{
    var path = this.Request.FilePath;
}

다음과 같이 여러 가지 정보를 얻기 위해 Page 객체의 속성을 사용할 수 있습니다.

  • Request. 이미 봤던 것처럼, Request는 브라우저가 생성한 요청의 종류, 페이지 URL, 사용자 식별정보 등 현재 요청에 대한 정보를 담고 있는 컬렉션입니다.
  • Response. Response는 서버 코드가 실행된 후 브라우저로 전송될 페이지 응답에 대한 정보를 담고 있는 컬렉션입니다. 예를 들면, 응답 페이지에 어떤 정보를 입력하기 위해서 이 속성을 사용할 수 있습니다.

@{
    // Url를 얻기 위해 페이지의 Request 객체에 접근합니다.
    var pageUrl = this.Request.Url;
}
<a href="@pageUrl">My page</a>

컬렉션 객체(배열과 딕셔너리)

컬렉션은 데이터베이스에서 가져온 Costomer 객체의 컬렉션처럼 동일한 형식을 가진 객체의 그룹입니다. ASP.NET에는 Request.Files 컬렉션 같은 내장 객체가 많이 있습니다.

컬렉션의 데이터로 작업하는 일은 빈번하게 일어납니다. 일반적인 두 가지 컬렉션 형식은 array와 dictionary입니다. 배열(array)은 일일이 변수를 생성하지 않고, 비슷한 항목들 묶어서 저장하고 싶은 경우 유용합니다.

@* Array block 1: 중괄호를 사용해서 새로운 배열을 선언합니다. *@

@{
    <h3>Team Members</h3>
    string[] teamMembers = {"Matt", "Joanne", "Robert", "Nancy"};
    foreach (var person in teamMembers)
    {
        <p>@person</p>
    }
}

배열을 사용할 때는 string, int, DateTime과 같이 특정 데이터 형식을 선언해야 합니다. 변수가 배열을 포함할 수 있음을 나타내려면 선언에 대괄호([])를 추가합니다. (예 : string[] 또는 int[]) 아이템의 인덱스나 foreach문을 통해 배열의 아이템에 접근할 수 있습니다. 배열의 인덱스는 0부터 시작합니다. 첫 번째 아이템의 인덱스는 0, 두 번째 항목의 인덱스는 1, 이런 식으로 이어집니다.

@{
  string[] teamMembers = {"Matt", "Joanne", "Robert", "Nancy"};
  <p>The number of names in the teamMembers array: @teamMembers.Length </p>
  <p>Robert is now in position: @Array.IndexOf(teamMembers, "Robert")</p>
  <p>The array item at position 2 (zero-based) is @teamMembers[2]</p>
  <h3>Current order of team members in the list</h3>
  foreach (var name in teamMembers)
  {
    <p>@name</p>
  }
  <h3>Reversed order of team members in the list</h3>
  Array.Reverse(teamMembers);
  foreach (var reversedItem in teamMembers)
  {
    <p>@reversedItem</p>
  }
}

Length 속성을 통해 배열의 아이템 수를 구할 수 있습니다. 특정 아이템의 인덱스를 구할 때는 Array.IndexOf 메서드를 사용합니다. 또 Array.Reverse 메서드를 통해 배열의 인덱스를 역순으로 만들 수 있고, Array.Sort 메서드로 배열을 정렬할 수 있습니다.

상기 코드에 의해 브라우저에 출력되는 결과는 다음과 같습니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573187/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-13_4.jpg

딕셔너리(dictionary)는 키(key)와 값(value)의 쌍으로 이루어진 컬렉션입니다. 값을 설정하거나 가져오기 위해서는 상응하는 키가 필요합니다.

@{
    var myScores = new Dictionary<string, int>();
    myScores.Add("test1", 71);
    myScores.Add("test2", 82);
    myScores.Add("test3", 100);
    myScores.Add("test4", 59);
}
<p>My score on test 3 is: @myScores["test3"]%</p>
@(myScores["test4"] = 79)
<p>My corrected score on test 4 is: @myScores["test4"]%</p>

딕셔너리 객체를 만들 때는 new 키워드를 사용합니다. var 키워드를 사용하여 변수에 딕셔너리 객체를 할당할 수 있습니다. 꺽쇠(<>)를 사용하여 딕셔너리 아이템의 데이터 형식을 선언합니다. 새로운 딕셔너리 객체를 만드는 것이므로, 선언의 끝에는 한 쌍의 괄호를 붙여주어야 합니다.

딕셔너리에 아이템을 추가할 때는 딕셔너리 변수(이 예제에서는 myScores)의 Add 메서드를 호출하고 키와 값을 지정합니다. 다음과 같이 대괄호([])와 키를 사용하여 값를 할당하는 방법도 있습니다.

myScores["test4"] = 79;

딕셔너리의 값을 찾을 때는 대괄호([])에 키를 넣으면 됩니다.

var testScoreThree = myScores["test3"];

매개변수를 가진 메서드 호출하기

이번 앞서 나온 예제들에서 보셨듯이, 객체는 메서드를 가질 수 있습니다. 예를 들면, Database 객체는 Database.Connect 메서드를 갖고 있을 수 있습니다. 많은 메서드들이 하나 또는 그 이상의 매개변수를 갖고 있습니다. 매개변수는 메서드를 호출할 때 메서드에 전달하는 값으로, 메서드는 넘겨 받은 매개변수를 사용할 수 있습니다. 다음 예제 코드는 3개의 매개변수를 갖는 Request.MapPath 메서드를 선언합니다.

public string MapPath(string virtualPath, string baseVirtualDir, bool allowCrossAppMapping);

이 메서드는 가상 경로를 매개변수로 받고, 대응되는 서버의 실제 경로를 반환합니다. 이 메서드의 매개변수는 virtualPath, baseVirtualDir, allowCrossAppMapping입니다. (매개변수는 입력 받게 될 데이터 형식과 함께 선언됩니다.) 이 메서드를 호출할 때는 반드시 3개의 매개변수를 모두 입력해야 합니다.

Razor구문은 메서드에 매개변수를 전달할 때 위치 매개변수(positional parameters) 나 명명 매개변수(named parameters) 둘 중 하나를 선택해서 사용할 수 있습니다. 위치 매개변수를 사용한다면 매개변수가 선언된 순서대로 매개변수를 전달합니다. 이 경우 모든 매개변수의 값을 전달해야 하고, 입력할 값이 없어도 건너뛸 수 없습니다. 입력할 값이 없는 경우 "" 이나 null을 입력합니다.

다음 예제는 웹사이트에 scripts라는 폴더가 있다고 가정합니다. 예제에서는 Request.MapPath 메서드를 호출하고 3개의 매개변수를 순서대로 입력합니다. 그리고, 메서드의 결과값을 출력합니다.

// 위치 매개변수를 사용하여 메서드에 매개변수를 전달합니다.
var myPathPositional = Request.MapPath("/scripts", "/", true);
<p>@myPathPositional</p>

메서드가 매개변수를 많이 가진 경우, 코드의 가독성을 높이기 위해 명명 매개변수를 사용할 수 있습니다. 명명 매개변수를 사용하는 경우, 매개변수명 뒤에 콜론(:)를 붙이고 값을 입력합니다. 명명 매개변수의 장점은 매개변수가 선언된 순서는 신경 쓰지 않아도 되고, 원하는 순서대로 매개변수를 전달할 수 있다는 것입니다. (단점은 매개변수명도 써야 하기 때문에 메서드 호출이 더 길어진다는 점입니다.)

다음 예제는 동일한 메서드를 명명 매개변수를 사용해서 호출한 예입니다.

// 명명 매개변수를 사용하여 메서드에 매개변수를 전달합니다.
var myPathNamed = Request.MapPath(baseVirtualDir: "/", allowCrossAppMapping: true, virtualPath: "/scripts");
<p>@myPathNamed</p>

위의 예제에서는 매개변수를 다른 순서로 전달했습니다. 하지만 실행되면 이전의 예제와 동일한 결과를 반환합니다.

에러 처리

Try-Catch 문

코드가 제어를 벗어나 실패하는 경우는 많이 있습니다. 예를 들면

  • 코드에서 파일을 열고, 만들고, 읽고, 쓰는 작업을 할 때 여러 가지 에러가 발생할 수 있습니다. 해당 파일이 없을 수도 있고, 잠겨 있거나, 파일을 다루기 위한 충분한 권한 없는 등 여러 가지 경우가 있을 수 있습니다.
  • 비슷한 예로 코드에서 데이터베이스의 레코드를 업데이트 하려고 하는 경우도 사용 권한 문제가 발생할 수 있고, 연결이 끊어지거나, 저장할 데이터가 유효하지 못한 경우 등 여러 가지 문제가 있을 수 있습니다.

프로그래밍 용어로는 이러한 경우를 예외(exception)라고 합니다. 프로그램에서 예외가 발생한다면, 잘해봐야 사용자를 짜증스럽게 하는 에러 메세지를 던져줄 것입니다.


출처 : http://i1.asp.net/umbraco-beta-media/2573199/Windows-Live-Writer_2--.NET-Web-Programming-Using-the-Razor-_7D39_ch02_programmingintro-14_4.jpg

예외가 발생할 때, 이런 식의 에러 메세지가 사용자에게 전달되는 것을 예방하기 위해 try/catch문을 쓸 수 있습니다. Try 문에서는 체크하고자 하는 코드를 실행합니다. 하나 또는 그 이상의 catch문에서는 발생할 수 있는 특정 에러를 처리할 수 있습니다. 예측할 수 있는 여러 가지 경우에 대해 catch문을 사용하여 에러를 처리할 수 있습니다.

주의 : try/catch문에서 Response.Redirect 메서드는 사용하지 않는 것이 좋습니다. Response.Redirect 메서드가 실행되어 페이지를 이동하면, 그 뒤에 있는 코드는 있어도 실행되지 않기 때문입니다. 설령 이동할 페이지 주소에 문제가 있어서 이동이 실패해도, 해당 페이지를 벗어났기 때문에 catch문으로 처리할 수 없습니다.

다음 예제는 첫 번째 요청에서 텍스트 파일을 생성하고, 사용자가 생성된 파일을 열 수 있는 버튼을 출력합니다. 이 예제는 예외를 발생시키기 위해, 의도적으로 잘못된 파일명을 사용합니다. 이 코드는 예측 가능한 두 가지 예외에 대해 catch문을 사용합니다. FileNotFoundException은 파일명이 틀린 경우에 대한 예외이고, DirectoryNotFoundException은 ASP.NET이 폴더조차 찾을 수 없는 경우에 대한 예외입니다(아래 예제는 주석을 풀면 제대로 동작하는 것을 볼 수 있습니다).

코드의 예외가 처리되지 않으면, 이전에 봤던 에러 페이지를 보게 됩니다. try/catch 문은 사용자가 이런 에러 페이지를 보는 일이 없도록 하는데 유용합니다.

@{
  var dataFilePath = "~/dataFile.txt";
  var fileContents = "";
  var physicalPath = Server.MapPath(dataFilePath);
  var userMessage = "Hello world, the time is " + DateTime.Now;
  var userErrMsg = "";
  var errMsg = "";

  if(IsPost)
  {
    // 사용자가 "Open File" 버튼을 눌러 페이지가 제출되면
    // 아래 코드에서 dataFile.txt 파일을 읽으려고 시도합니다.
    try {
      // 이 코드는 잘못된 파일 경로 때문에 실패합니다.
      fileContents = File.ReadAllText(@"c:\batafile.txt");

      // 이 코드는 페이지의 에러를 제거하고, 정상적으로 동작하도록 합니다.
      // 아래 코드의 주석을 해제하고 바로 위의 코드를 주석으로 처리하면 됩니다.
      //fileContents = File.ReadAllText(physicalPath);
    }
    catch (FileNotFoundException ex) {
      // 디버깅, 로깅.. 등을 위해 예외 객체를 사용할 수 있습니다.
      errMsg = ex.Message;
      // 사용자가 이해하기 쉬운 에러 메시지를 만듭니다.
      userErrMsg = "A file could not be opened, please contact "
        + "your system administrator.";
    }
    catch (DirectoryNotFoundException ex) {
      // 이전 예외와 유사합니다
      errMsg = ex.Message;
      userErrMsg = "A directory was not found, please contact "
        + "your system administrator.";
    }
  }
  else
  {
    // 페이지가 처음 요청되었을 때, 텍스트 파일을 만듭니다
    File.WriteAllText(physicalPath, userMessage);
  }
}

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Try-Catch Statements</title>
  </head>
  <body>
  <form method="POST" action="" >
    <input type="Submit" name="Submit" value="Open File"/>
  </form>

  <p>@fileContents</p>
  <p>@userErrMsg</p>

  </body>
</html>

authored by


 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})