logo
border border
              
border border
border border
  Post Subject :: #86. VS 2008을 이용한 블로그 프로그래밍 - Part7     [ASP.NET]
border border
border border
     
이 포스트는 월간 마이크로소프트웨어에 기고한 원고를 재편집한 포스트입니다. 그러므로, 본의 아니게 반말로 진행되고 있습니다. 원래 싸가지가 없어서 그런 것이 아니니 무한 용서를... ^^;;
또한, .NET Framework 3.5 SP1이 적용되기 이전의 소스이므로, 현재의 개발 환경과 다를 수 있습니다. 마소에 제출한 블로그 소스는 블로그 소스 다운로드에서 다운로드하실 수있습니다.

블로그의 포스트 목록 기능 구현

<화면 11>에서와 같이 작성된 포스트의 목록을 보여줄 때, 포스트의 정보가 저장되는 BLOG_POSTS 테이블만으로는 분류(카테고리) 정보를 알아올 수 없으므로, BLOG_POSTS 테이블과 BLOG_CATEGORIES 테이블을 조인하는 뷰를 만들어 포스트의 목록을 보여주도록 한다. "서버 탐색기(Server Explorer)"에서 사용 중인 연결 정보를 확장하여 나타나는 View 항목에 우측 마우스를 클릭하여 "새 뷰 추가(Add New View)" 메뉴를 선택한다. 그러면, View에 사용될 테이블을 추가하는 화면이 <화면 12>와 같이 나타나게 된다.


<화면 12> View에 사용할 테이블을 추가하는 화면

여기에서 BLOG_CATEGORIES 테이블과 BLOG_POSTS 테이블을 선택한 후 "추가(Add)" 버튼을 클릭한 후, "닫기(Close)" 버튼을 클릭하여 테이블 추가 화면을 닫는다. 그리고, <화면 13>과 같이 View를 구성한 후, 새로운 View명을 "VIEW_POSTLIST"라고 변경한 후 저장한다.


<화면 13> "VIEW_POSTLIST" 뷰 구성

새로 생성한 "VIEW_POSTLIST" 뷰의 쿼리문은 다음과 같다.

SELECT dbo.BLOG_CATEGORIES.categoryid, dbo.BLOG_CATEGORIES.categoryname,
    dbo.BLOG_POSTS.postid, dbo.BLOG_POSTS.postname, dbo.BLOG_POSTS.postcontent,
    dbo.BLOG_POSTS.createdate, dbo.BLOG_POSTS.viewcount,
    dbo.BLOG_POSTS.commentcount, dbo.BLOG_POSTS.tag
FROM dbo.BLOG_CATEGORIES
INNER JOIN dbo.BLOG_POSTS
ON dbo.BLOG_CATEGORIES.categoryid = dbo.BLOG_POSTS.categoryid
WHERE (dbo.BLOG_POSTS.deletedate IS NULL)


새로 생성한 "VIEW_POSTLIST" 뷰를 "BlogDataClasses.dbml" 파일 디자이너의 좌측 영역으로 드래그 앤 드랍하여, 뷰의 스키마를 추가한다. 포스트 목록과 공지사항 목록은 Visual Studio 2008에서 새롭게 추가된 LinqDataSource 컨트롤을 사용하고 있으며, LinqDataSouce 컨트롤을 데이터 소스로 하여 ListView 컨트롤에 데이터를 출력하게 하고 있다. "BlogDataClasses.dbml" 파일에 추가된 "VIEW_POSTLIST" 뷰 스키마는 포스트 목록에서 사용되는 LinqDataSource 컨트롤에서 사용할 것이다. 또한, DataPager 컨트롤을 ListView 컨트롤과 연결하여 DataPager 컨트롤로 하여금 페이징 기능을 구현하도록 하였다. 포스트의 목록에 관련된 소스 코드는 이달의 디스켓을 참고하기를 바라며, 공지사항의 목록 구현도 포스트의 목록 구현과 동일한 방식을 취하고 있으므로 이에 대한 설명은 생략하도록 한다.

포스트 목록과 공지사항 목록을 보여주기 위해 ListView 컨트롤을 사용하고 있다. 목록에서 사용되는 ListView 컨트롤은 3개의 템플릿을 가지고 있으며, 각 템플릿의 기능은 다음과 같다.

● LayoutTemplate : 포스트 및 공지사항의 목록을 보여주는 전체적인 테이블의 레이아웃을 정의하는 템플릿으로, 목록의 헤더 부분과 DataPager 컨트롤을 사용한 페이징 부분의 코드가 정의되어 있다.
● ItemTemplate : 반환되는 포스트 및 공지사항의 데이터를 LayoutTemplate에서 정의한 레이아웃에 맞게 구성하는 템플릿으로, ItemTemplate에 정의되는 각 아이템들은 ListView 컨트롤의 ItemPlaceholderID 속성에 정의된 PlaceHolder 컨트롤의 위치에 렌더링시 포함되게 된다.
● EmptyDataTemplate : 반환되는 포스트 및 공지사항의 데이터가 없을 경우, 화면에 보여지고자 하는 영역을 정의하는 템플릿이다.

따라서, 포스트 및 공지사항의 데이터가 있을 경우는 LayoutTemplate 템플릿과 ItemTemplate 템플릿에 정의된 코드로 렌더링되어 화면에 보여지게 되고, 만약 데이터가 없을 경우는 <화면 14>처럼 EmptyDataTemplate 템플릿에 정의된 코드가 화면에 보여지게 된다.


<화면 14> 데이터가 없을 경우의 화면

또한, 목록에 관련된 페이징을 위한 DataPager 컨트롤을 ListView 컨트롤과 연결시키기 위해서는 DataPager 컨트롤의 PagedControlID 속성을 이용하여 ListView 컨트롤의 ID를 지정하면, DataPager 컨트롤을 이용한 페이징을 구현할 수 있다. DataPager 컨트롤에서 이용할 수 있는 페이저 필드는 3개가 있으며, 각각의 페이저 필드와 그에 대한 설명은 다음과 같다.

● NextPreviousPagerField : 이전 페이지, 다음 페이지 그리고 첫 페이지 또는 마지막 페이지로 이동할 수 있는 페이징 기능을 제공한다.
● NumericPagerField : 페이지 번호가 표시되어 페이지 번호를 클릭할 시에 클릭한 페이지로 이동할 수 있는 페이징 기능을 제공한다.
● TemplatePagerField : 개발자가 임의로 페이징의 기능을 구현할 수 있는 페이저 필드이다.

필자는 NumericPagerField 페이저 필드를 이용해서 페이징을 구현하였으며, NextPreviousPagerField 페이저 필드를 사용하여 페이징을 구현하는 경우의 화면은 <화면 15>와 같다.


<화면 15> NextPreviousPagerField 페이저를 사용한 페이징 화면


블로그의 포스트 수정 및 삭제 기능 구현

포스트 목록 탭에 있는 포스트의 목록에서 작성된 포스트의 제목을 클릭하면, fnMoveModify()라는 이름의 자바스크립트 함수를 호출하며, 이 함수는 <리스트 6>에 보여지는 페이지 메소드를 호출하며, 페이지 메소드에서 반환된 테이블의 엔티티 정보를 포스트 수정 탭에 있는 항목에 표시하게 된다.

    // 포스트 정보를 가져온다.
    [System.Web.Services.WebMethod]
    public static VIEW_POSTLIST GetPostInfo(string strPostID)
    {
        blogDataStaticContext = new BlogDataClassesDataContext();
        VIEW_POSTLIST blogPostList = 
            blogDataStaticContext.VIEW_POSTLIST.Single(q => q.postid == strPostID);
        blogPostList.postcontent = HttpUtility.HtmlDecode(blogPostList.postcontent);
        blogDataStaticContext = null;
        return blogPostList;
    }
<리스트 6> 페이지 메소드의 코드

수정할 항목을 수정한 후, 화면 하단의 수정 버튼을 클릭하면 변경된 제목 및 본문, 그리고 태그 정보가 반영되며 포스트 목록 탭으로 이동하게 된다. 포스트 목록 탭에서는 수정된 정보가 반영된 포스트 목록이 나타나게 된다. 화면 하단의 삭제 버튼을 클릭하면 <리스트 7>에서 보여지는 코드가 실행되어, 해당 포스트의 정보가 삭제된다. (실제 데이터 삭제가 아닌, BLOG_POSTS 테이블의 deletedate 필드에 현재 날짜 정보가 입력되게 된다.) 그리고, 포스트 목록 탭으로 이동하게 되며 포스트 목록 탭에는 삭제한 포스트의 정보가 나타나지 않게 된다.

    // 포스트 수정 탭에서 삭제 버튼 클릭 시
    protected void btnPostDelete_Click(object sender, EventArgs e)
    {
        try
        {
            string strPostID = hidPostID.Value;
 
            if (!string.IsNullOrEmpty(strPostID))
            {
                // 공지사항 CheckBox가 체크되어 있으면 공지사항 삭제
                if (chkModifyNotice.Checked)
                {
                    // DeleteDate 필드를 현재의 시간으로 업데이트
                    BLOG_NOTICES blogNotice =
                        blogDataContext.BLOG_NOTICES.Single
                        (q => q.noticeid == int.Parse(strPostID));
                    blogNotice.deletedate = DateTime.Now;
                    blogDataContext.SubmitChanges();
                    SetNoticeListDataBound();
                    ScriptManager.RegisterClientScriptBlock(
                        this, this.GetType(), "setindex", "fnSetTablIndex('3')", true);
                }
                else
                {
                    // DeleteDate 필드를 현재의 시간으로 업데이트
                    BLOG_POSTS blogPost =
                        blogDataContext.BLOG_POSTS.Single(q => q.postid == strPostID);
                    blogPost.deletedate = DateTime.Now;
                    blogDataContext.SubmitChanges();
                    SetPostListDataBound();
                    ScriptManager.RegisterClientScriptBlock(
                        this, this.GetType(), "setindex", "fnSetTablIndex('2')", true);
                }
 
                SetInitForm();
            }
        }
        catch (Exception ee)
        {
            ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "error"
                , "alert('" + ee.Message + "::" + ee.Source + "::" + ee.InnerException + "')", true);
        }
    }
<리스트 7> 삭제 버튼 클릭 시의 소스 코드

최신 포스트 목록 출력하기

자신의 블로그를 방문하는 사용자에게 작성된 포스트 중에서 최신 포스트의 제목 및 간단한 정보를 보여주게 하기 위해서 "Default.aspx" 페이지에, 작성된 포스트 중에서 날짜순으로 정렬하여 3개의 최신 포스트 정보를 가져오는 코드를 <리스트 8>과 같이 추가한다.

    // 최근 포스트 목록 가져오기
    private void GetRecentPostList() 
    {
        BlogDataClassesDataContext blogDataContext = new BlogDataClassesDataContext();
 
        // 포스트의 목록 중 최근의 3개의 목록만을 가져온다.
        List<VIEW_POSTLIST> recentlyPost 
            = (from c in blogDataContext.VIEW_POSTLIST
                orderby c.createdate descending
                select c).Skip(0).Take(3).ToList();
 
        LvwRecentPostList.DataSource = recentlyPost;
        LvwRecentPostList.DataBind();
 
        blogDataContext = null;
    }
<리스트 8> 최신 포스트 정보를 가져오는 소스 코드

"Default.aspx" 페이지의 소스를 수정한 후, 블로그를 방문하는 사용자가 보게 될 초기 화면은 <화면 16>과 같이 된다.

<화면 16> 블로그의 초기 화면

이상으로, 포스트를 작성, 수정 그리고 삭제하는 기능 및 Visual Studio 2008에서 새롭게 추가된 컨트롤인 ListView 컨트롤과 DataPager 컨트롤, 그리고 LinqDataSource 컨트롤을 사용하여 작성된 포스트의 목록을 화면에 출력하는 방법에 대해서 알아보았다. 다음 호에서는 포스트 조회 화면 및 댓글의 작성/수정/삭제의 기능, 그리고 RSS 기능 구현 등 블로그에 필요한 기능을 구현하는 방법에 대해서 설명하도록 하겠다.


Creative Commons License
저작물크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
border border
border border
  이전 포스트 :: #85. VS 2008을 이용한 블로그 프로그래밍 - Part6
  다음 포스트 :: #87. VS 2008을 이용한 블로그 프로그래밍 - Part8
border border
border border
  
# Commented By :: 용하운 At 2/24/2009 8:10:00 PM [D]
안녕하세요~~ 한가지 궁금한점이...
블로그 포스트 수정부분에서 제목을 클릭하면 자바스크립트 함수
fnMoveModify(postID, mode)
를 호출하고 페이지 메서드를 통해서 해당 정보를 가져오게 되있는데
PageMethods.GetPostInfo(postID, fnMoveModifyPost_Complete, fnPageMethods_Fail);
소스와 차이가 없는데 스크립트 오류가 계속 나는데요...개체가 필요하다는...
# Commented By :: dekiriya At 2/24/2009 8:58:44 PM [D]
이상하네요.
저는 포스트목록이나 공지목록에서 클릭으로 불러와서 수정하면 제대로 수정되는데요.

# Commented By :: dekiriya At 2/25/2009 2:10:55 AM [D]
강좌 잘보고 있습니다.

PostView.aspx 파일에 스타일시트를 첨부할려고 링크를 거니깐
문법에러가 나네요.
콘덴츠 파일에선 링크를 어떻게 걸수 있나요?
# Commented By :: 최지훈 At 3/4/2009 3:21:40 PM [M] [D]
용하운 :: AJAX 익스텐션이 무언가 충돌이거나 버전이 안 맞아서 일어나는 오류일수 있습니다. 다시 한 번 확인하시기 바랍니다...

dekiriya :: 컨텐츠 파일에서는 컨텐츠 페이지에 기본적으로 정의되는 컨텐츠 중 첫 번째 컨텐츠 컨트롤인 ContentPlaceHolderID가 head인 컨트롤 안에 정의해주시면 됩니다.
# Commented By :: 뚜뚜 At 4/24/2009 1:57:32 PM [D]
안녕하세요. 강좌를 보며 하나하나 따라하고 있는 중입니다. 우선 이렇게 좋은 강좌를 볼 수 있음에 감사드리구요.
질문은 admin.cs파일에 보면 dbo.usp_GetArchivePostsInfo dbo.usp_SetArchivesCount dbo.usp_SetTagInfo dbo.usp_GetVisitInfo 의 프로시저가 필요한데 해당 소스는 어디에 있는 걸까요? 알려주시면 감사하겠습니다. ^^;
# Commented By :: deKKIL At 4/24/2009 11:53:54 PM [D]
http://www.neostyx.net/GrayRound/NXBlogPostView.aspx?postid=090309083809673&categoryname=ASP.NET
연재 9번 게시물이 되겠네요.
댓글에 필요한 프로시저들이 망라되어(?) 있습니다.;

그나저나 언제쯤 강좌가 다시 올라올란지.........;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
# Commented By :: Woos At 6/2/2009 3:33:22 PM [D]
<리스트 6>에서 q => q.postid == strPostID 이부분에서 자꾸 에러가 나는 것 같은데
'q' 는 어떤값인가요??
# Commented By :: 123 At 11/17/2009 12:43:47 PM [D]
123
  NAME ::   PASSWORD ::
  MAIL ::   HOMEPAGE ::
  COMMENT ::
border border
border border
COPYLEFT NX Blogs.   opml

LogIn ]  [ Join NX Blog's ]
border border
border border
mvp
border border
border border
  border
   Personal Thought
   ASP.NET
   ASP.NET AJAX
   ASP.NET MVC Framework
   Dev Story(Etc.)
   Reading the Articles
   About Microsoft / MSDN
   Certification Talk
   Useful Dev Tools
border border
border border
  border
   2010 년 09 월 (1)
   2010 년 06 월 (1)
   2010 년 05 월 (1)
   2010 년 04 월 (1)
   2010 년 03 월 (1)
   2010 년 02 월 (5)
   2010 년 01 월 (1)
   2009 년 04 월 (2)
   2009 년 03 월 (3)
   2009 년 02 월 (6)
   2009 년 01 월 (1)
   2008 년 10 월 (1)
   2008 년 06 월 (8)
   2008 년 05 월 (10)
   2008 년 04 월 (13)
   2008 년 03 월 (9)
   2008 년 02 월 (17)
   2008 년 01 월 (5)
   2007 년 12 월 (8)
   2007 년 11 월 (15)
   2007 년 10 월 (36)
   2007 년 09 월 (33)
   2007 년 08 월 (17)
   2007 년 07 월 (23)
   2007 년 06 월 (4)
   2007 년 05 월 (16)
   2007 년 04 월 (26)
   2007 년 03 월 (14)
   2007 년 02 월 (25)
   2007 년 01 월 (41)
   2006 년 12 월 (38)
   2006 년 11 월 (0)
   2006 년 10 월 (0)
   2006 년 09 월 (1)
   2006 년 08 월 (9)
   2006 년 07 월 (1)
border border
border border
  border
   #128. 無題
    By 최지훈 At 9/3/2010
   127. [예약구매] 실전. jQ...
    By 최지훈 At 6/13/2010
   #126. 무제
    By 최지훈 At 5/23/2010
   #125. 요즘 근황?
    By 최지훈 At 4/15/2010
   #124. ASP.NET 4 책을...
    By 최지훈 At 3/12/2010
   #97. ASP.NET 4 New...
    By 최지훈 At 2/12/2010
   #96. ASP.NET 4 New...
    By 최지훈 At 2/10/2010
   #95. ASP.NET 4 New...
    By 최지훈 At 2/9/2010
   #94. ASP.NET 4 New...
    By 최지훈 At 2/2/2010
   #93. ASP.NET 4 New...
    By 최지훈 At 2/1/2010
border border
border border
  border
   배는숨겨야지 에서 나도 모르게 빵...
    By ㅋㅋ At 8/17/2010
   Sorry. I don't hav...
    By 최지훈 At 8/16/2010
   내 생애 번역서는 이걸루 끝이다....
    By 최지훈 At 8/16/2010
   네..^^;; 저도 감사합니다.
    By 최지훈 At 8/16/2010
   IIS 버전이 업그레이드되면서 해...
    By 최지훈 At 8/16/2010
   나중에 비슷한 차로 태워는 줄께~...
    By 최지훈 At 8/16/2010
   나도 사주세요 저 차
    By ㅋㅋ At 8/12/2010
   저도 URL Rewriting 이...
    By 초보 At 8/7/2010
   감사드립니다^^
    By 이한철 At 7/28/2010
   오우~ 형 ㅊㅋㅊㅋ해~ 결국 했구...
    By 산티아고 At 7/26/2010
border border