오늘 쓴 따끈따끈한 강좌입니다. 그래봐야 10원짜리지만.


Razor 초급 강좌 중에 section 이 있다. ASP.NET 클래식으로 치자면 MasterPage 아래 ContentPlaceHolder 역할을 담당한다.

일단 Razor 의 section 과 layout 에 대한 개념은 이 링크를 참조한다.

 

일단 section 을 추가하다는 예를 들어보자.

먼저 레이아웃이 잡힌 페이지에서는 이렇게 하고

  1.           @RenderSection("MySection", false)
              

그다음 그 하위 페이지에서 section을 뿌릴라면 이렇게 한다.

  1.           @section MySection{
              <nav class="submenu">
                  <a href="@Href("./")">상품목록</a>
                  <a href="@Href("Write")">상품등록</a>
              </nav>
              }
              

그렇다면 section에 내용 말고 원하는 페이지를 대신 넣어줄라면 어떻게 하는가? 간단하다.

  1.           @section MySection{
              @RenderPage("~/Path/Page.cshtml");
              }
              

이렇게 하면 예를 들어 서브메뉴를 뿌린다는 용도같이 각 페이지마다 똑같은 내용을 넣는다면 이게 유리하긴 하다.

하지만 이것도 좀 왠지 좀 그렇다. section 선언하고 안에 렌더링 뿌려야 하다니 보기 안좋지 아니한가?

그렇다고 해서 이렇게 하는 것도 없고...

  1.           @IncludeSection("MySection", "~/Path/Page.cshtml")
              

물론 위 메서드는 없기 때문에 오류를 뿌린다. 그렇다고 포기 말라. 없으면 만들면 된다.

어렵지 않다. App_Code 에 아무 클래스 파일 추가해 주시고. 확장 메서드를 만들면 된다.

section 에 페이지를 렌더링하는 간단한 메서드 IncludeSection 메서드 개봉박두!

  1.               public static void IncludeSection(this WebPageBase page, string section, string path)
                  {
                      page.DefineSection(section, () => { page.Write(page.RenderPage(path)); });
                  }
              

WebPageBase에 대한 확장 메서드를 만들어 재낀다. 어자피 모든 Razor 페이지는 WebPageBase에 상속된다.

만약 Razor 외에 다른 템플릿이 있다면? 그땐 좀 생각해보고. 어쨌든 어떤 역할을 하는지 친절히 설명해 주시겠다.

먼저 DefineSection 부터 참고하자. 이녀석은 이렇게 정의되어 있다.

  1.           public void DefineSection(string name, SectionWriter action);
              

첫번째 인자는 섹션 이름이고, 두번째 인자는 섹션 내용을 쓸 대리자다. 인자 없고 리턴값 void니 편하게 쓴다.

얘는 레이아웃 페이지에 상속이 되어 있는 section을 선언하여 부모 페이지에 뿌려주기 위한 초석을 제공한다. 즉,

  1.           @section MySection{
                  <p>내용 솰라솰라</p>
              }
              

 

이렇게 코딩한다면 런타임에서는 이런 식으로 해석된다.

  1.                   this.DefineSection("MySection", () =>
                      {
                          this.Write(new HtmlString("<p>내용 솰라솰라</p>"));
                      });
              

올ㅋ편리하다.

어쨌든 DefineSection 이 어떤놈인지 알았으니 이제 내용을 쓰는 일만 남았다. RenderPage 메서드를 쓰면 된다.

하지만 그냥 쓰면 안된다. 이 메서드는 HelperResult 를 반환한다. 즉. 내용이 반환된다는 것이다. 여기에 주의해야 한다.

SectionWriter 대리자는 void가 반환된다. 스트림에 쓰지 않는다. 직접 써야 한다는 것이다. 그래서 Write 메서드에 감싼 것이다.

결국 우린 이렇게 쓸필요 없고,

  1.           @section MySection{
              @RenderPage("~/Path/Page.cshtml");
              }
              

이렇게 쓸필요도 없고,

  1.                   this.DefineSection("MySection", () =>
                      {
                          this.Write(this.RenderPage("~/Path/Page.cshtml"));
                      });
              

조금 고생해서 이 메서드 한줄이면

  1.           @IncludeSection("MySection", "~/Path/Page.cshtml")
              

위와 똑같은 효과를 발휘한다는 것이다.

얼마나 편리한가? 개발자에게 귀차니즘은 축복을 명심하라 일러두면서 오늘 강좌는 쿨하게 끝.





profile
20대 언제나 쿨한 개발(犬足)자.