반응형
이 포스트는 월간 마이크로소프트웨어에 기고한 원고를 재편집한 포스트입니다. 그러므로, 본의 아니게 반말로 진행되고 있습니다. 원래 싸가지가 없어서 그런 것이 아니니 무한 용서를... ^^;;
또한, .NET Framework 3.5 SP1이 적용되기 이전의 소스이므로, 현재의 개발 환경과 다를 수 있습니다. 마소에 제출한 블로그 소스는 블로그 소스 다운로드에서 다운로드하실 수있습니다.
또한, .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)
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 페이저를 사용한 페이징 화면
● 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;
}
수정할 항목을 수정한 후, 화면 하단의 수정 버튼을 클릭하면 변경된 제목 및 본문, 그리고 태그 정보가 반영되며 포스트 목록 탭으로 이동하게 된다. 포스트 목록 탭에서는 수정된 정보가 반영된 포스트 목록이 나타나게 된다. 화면 하단의 삭제 버튼을 클릭하면 <리스트 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);
}
}
최신 포스트 목록 출력하기
자신의 블로그를 방문하는 사용자에게 작성된 포스트 중에서 최신 포스트의 제목 및 간단한 정보를 보여주게 하기 위해서 "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;
}
"Default.aspx" 페이지의 소스를 수정한 후, 블로그를 방문하는 사용자가 보게 될 초기 화면은 <화면 16>과 같이 된다.
<화면 16> 블로그의 초기 화면
이상으로, 포스트를 작성, 수정 그리고 삭제하는 기능 및 Visual Studio 2008에서 새롭게 추가된 컨트롤인 ListView 컨트롤과 DataPager 컨트롤, 그리고 LinqDataSource 컨트롤을 사용하여 작성된 포스트의 목록을 화면에 출력하는 방법에 대해서 알아보았다. 다음 호에서는 포스트 조회 화면 및 댓글의 작성/수정/삭제의 기능, 그리고 RSS 기능 구현 등 블로그에 필요한 기능을 구현하는 방법에 대해서 설명하도록 하겠다.
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
반응형
'Program > ASP.NET' 카테고리의 다른 글
VS2008 블로그 프로그래밍 SQL (0) | 2009.06.16 |
---|---|
VS 2008을 이용한 블로그 프로그래밍 - Part8 (0) | 2009.06.16 |
VS 2008을 이용한 블로그 프로그래밍 - Part6 (0) | 2009.06.16 |
VS 2008을 이용한 블로그 프로그래밍 - Part5 (0) | 2009.06.16 |
VS 2008을 이용한 블로그 프로그래밍 - Part4 (0) | 2009.06.16 |