관리 메뉴

새로운 시작, GuyV's lIfe sTyle.

닷넷 게시판 만들기 Part 42 본문

ⓟrogramming/asp.net 게시판

닷넷 게시판 만들기 Part 42

가이브 2011.06.08 17:55

 

2011/05/13 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 31
2011/05/16 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 32
2011/05/18 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 33
2011/05/19 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 34
2011/05/23 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 35
2011/05/25 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 36
2011/05/26 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 37
2011/05/27 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 38
2011/05/30 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 39
2011/05/31 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 40
2011/06/01 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 41


1. 닷넷 개발환경 준비, 테스트
2. 닷넷 알아보기 [7/7]
3. asp.net 컨트롤 [10/10]
4. 데이터베이스(DB) [7/7]
5. 닷넷 게시판을 만들어보기 전에.. [4/4]
6. 게시판 만들기 [12/..]



시작하기전에, 다음 파일을 다운로드 받아 현재 게시판의 홈디렉터리에 넣자.


그리고 top.ascx 파일을 열어서 <head>..</head> 태그 사이에 다음처럼 진한 부분을 추가하도록 하자.


(..)

<html>
<head>
<title>닷넷 게시판 만들기</title>

<link rel="stylesheet" type="text/css" href="/default.css">


</head>
<body>

(..)




웹은 디자인, 프로그램 개발, 그리고 자료를 저장하기 위한 데이터베이스 설계 등 여느 프로그램처럼 각각의 분야가 따로 있다. 그 중에서 방금 추가한 것은 디자인에 관련된 요소이다. (CSS라는 것인데, 자료는 따로 찾아보시기 바란다) 맞은 사람이 아픔을 느낀다고, 필자처럼 주위에 디자이너가 없으면 어쩔 수 없이 스스로 배워야 될 것이다 ^_^

지난 시간에 이어서 글읽기 페이지를 계속 다루도록 하자.
조회수는 글읽기 페이지인 board_view.aspx 가 열릴 때 자동으로 올라가게 된다. 현재 글의 조회수 컬럼을 수정하는 쿼리를 만들면 되겠다. UPDATE 문을 사용하자. 쿼리문을 만들 때 "변수"로 들어가는 것은 임시로 "상수"로 넣어 예상되는 결과에 대해 테스트를 해본 다음에 프로그램에 적용시키는 버릇을 들이면 편하다.


UPDATE board SET readnum=readnum+1 WHERE category='test' AND board_id=1


test 카테고리의 고유번호 1번 게시물을 읽었을 때 위의 쿼리문을 실행하면 조회수 컬럼인 readnum 이 현재 값에서 +1 이 되어 조회수를 구현할 수 있다.

Board.csReadUp(..) 이라는 메서드명으로 만들자. 이 메서드는 자동으로 board_view.aspx 에서 호출될 것이다. 결과로 내놓을 리턴은 없고, 필요한 인수는 기본적으로 카테고리와 고유번호 2개이다. 글조회 메서드인 Read(..) 와 거의 동일하다.



그리고 이 메서드는 board_view.aspx 의 IsPostBack 이 아닐 때, 그러니까 처음 열렸을 때만 실행해주자. 댓글이 달릴 때마다 페이지가 다시 열릴테니 말이다.



프로세스 플로우상 위의 메서드는 Page_Load() 의 맨 하단에 있기 때문에 화면에는 방금 열린 조회수가 적용되지 않은 컬럼값이 나오게된다. (lblRead.Text 값이 할당된 후에 실행) 원한다면 위치를 변경하여 조회수 업데이트가 이루어진 후에 적용된 값이 잘 나오도록 하면 되겠다. 

이제 추천기능을 구현해보도록 하자. 추천 기능도 별거 있겠는가? 추천 버튼을 누르면 추천수 값을 가지고 있는 컬럼인 recommend 를 조회수처럼 +1 해주면 된다. 추천버튼은 글 내용의 맨 마지막에 <center>..</center>를 감싸주어 눈에 잘 띄게 중앙 정렬로 한다. 이 정도 구현은 생략하도록 하겠다. 본인이 직접 꼭 해보시기 바란다.

유의할점은, (1)비회원의 추천가능여부 (2)추천 중복체크 정도가 될 수 있다. 비회원이 추천을 가능하게 한다면, 추천의 중복은 막을 방법이 없다. 접속자의 IP를 체크하여 당장에 막을 수는 있겠지만, 이는 다음 접속시 IP가 바뀔 수 있는 가능성이 있다. 일반적으로 비회원의 중복 추천은 원천적으로 차단할 수가 없다. 쿠키(Cookie)를 쓴다고 해도 사용자가 지워버리면 그만이다. 그러므로 회원만 가능하게 하는 것이 좋을 것 같다.

회원은 실제 우리가 운영하는 홈페이지에 DB 값으로 저장되어 있기 때문에, 회원ID로 게시물 n번의 글을 추천했던 기록을 남기면 된다. 어디에? 귀찮겠지만 DB 테이블을 따로 만들어주도록 한다. 여기에는 추천한 번호(board_id)와 누가 추천했는지(user_id)만 저장하면 된다. 추천할 때마다(혹은 글 조회시에) 따로 만든 테이블에 해당 글과 세션값 ID로 자료가 있는지 체크한 후, 있다면 이미 추천하였으므로 더 추천할 수 없도록 하면 되겠다. 

프로그램의 기능을 만들 때는 언제나 머릿속으로 순서를 하나하나 정하도록 하자. 충분히 생각지도 못한 상황이 발생할 수가 있다. 그러나 문제될 것은 없다. 해결하면 되니까. 경험(경력)이 많다는 것은 이런 문제점을 모두 다 예상할 수 있는 사람들이다. 

어쨌든, 필자는 회원만 추천버튼이 보이게 할 것이고 추천 중복 처리는 하지 않겠다. (중복 처리)방법은 이미 알려드렸으니 본인이 꼭 해보시길 바란다. 하나하나 키보드로 쳐서 직접 구현을 해 봐야 자기 것이 된다.
비슷한 케이스로 조회수 증가 문제도 생각해보자. 현재로서는 새로 고침을 해주면 하는 대로 계속 올라갈 것이다.



이렇게 board_view.aspx 의 내용이 출력되는 곳 하단에 추천하기 버튼을 넣고, 클릭 이벤트도 걸어주도록 하자.
Board.cs 에 구현할 메서드 이름은 Recommend(..) 라고 하자. 조회수를 올려주는 메서드와 다를바 없이 거의 똑같이 구현하면 되겠다. (이 때 필요한 고급 스킬이  Ctrl + C, Ctrl + V 이다. ^^)



결과적으로 추천을 하면 이제 더 이상 버튼은 누를 수 없고, "이미 추천하였습니다."와 같은 메시지를 보여주게 될 것이다. 페이지가 처음 로드될 때 이렇듯 이미 추천되었는지 체크를 할 필요가 있겠다. 이 강의에서는 사실 설명하고 함께 해봐야 이미 여러분들이 구현 스킬을 갖추셨기 때문에 별 의미가 없다고 판단하겠다. 

이제 지금 읽고 있는 글의 수정/삭제 기능을 만들어보도록 하자.
글을 수정, 삭제할 수 있는 권한은 관리자이거나 게시물을 올린 사람이다. 우리가 구현하지는 않았으나 관리자 기능은 따로 관리자 ID를 정하고, 그 ID로 로그인할 때 관리자 세션 값을 따로 주면 어디서든 파악할 수 있겠다.

수정, 삭제버튼은 글 내용의 <tr>..</tr>밑에 <tr>태그 하나를 더 만들어서 한 줄을 추가하도록 하자. 그리고 이 <tr>태그를 서버컨트롤로 만들고 기본적으로 숨겨놓자. 현재 페이지를 연 사람이 가지고 있는 세션값이 글 쓴 사람의 user_id 컬럼과 같다면 수정,삭제 권한이 있으므로 보여주기로 한다. 다시 말하지만 이는 필자가 생각하는 방법일 뿐이다.

이 기능을 구현해보자.



이렇게 버튼을 수정, 삭제 버튼을 원하는 위치에 놓고,





로그인을 했는지 체크한 후, 로그인 했다면 현재 글을 작성한 ID와 세션값이 같은지 비교한다. 같다면 범인(?)이므로 trModifyDelete 컨트롤의 Visible 속성을 'true'로 주어 버튼을 누를 수 있게 보여준다. 지금은 'test' 라는 고정 세션값을 주고 있기 때문에 무조건 보여주겠지만 다른 세션값을 가졌다면 숨겨질 것이다.

디자인은 완료 되었으니 이제 "수정"기능에 대해 고민해보자. 수정기능은 현재 글의 내용에서 사용자가 입력한 항목을 다시 입력받게 하여 수정하는 기능이다. 우리 게시판에는 '제목, 내용, 파일첨부' 이렇게 세 가지를 입력받는다. 이것을 그대로 불러와서 보여준 후, 사용자가 수정하고 "완료"버튼을 누르면 수정된 내용을 다시 업데이트 하면 되는 기능이다. 다른 값들인 "조회수, 글고유번호, 추천, 작성일시"등은 변동사항이 없다. 

글 수정 폼은 새로 만들 수도 있겠지만, 디자인은 board_write.aspx 와 별반 다를게 없으므로 여기에 수정 기능을 붙여서 사용할 수도 있다. 우리는 board_write.aspx 에 수정 기능을 덧붙여보도록 하자.

일단 글 수정을 위해서는 현재 board_write.aspx 에서 받는 카테고리 값인 "c"에를 포함해서 따로 글 번호를 하나 더 받아야 된다. "어떤 글을 수정할거냐?"를 알려주기 위해서이다. 이 변수는 글읽기처럼 "n"으로 정하자. 그러면서 board_write.aspx 에서는 "n" 변수가 넘어온다면 글수정 기능이므로 수정모드로 바뀌면 되겠다.

board_write.aspx 를 열고 앞서 말한것 대로 구현해보자. 기존의 Page_Load() 는 깨끗하게 비워져있다.



글쓰기 버튼의 이벤트에서 수정모드가 아니라면 기존의 기능대로 처리하면 된다. 그러나 수정기능일 때는 달라져야한다. 이 기능을 위해 간편하게 bool 형 변수인 "IsEditMode"를 선언해서, 이를 체크하는 방법으로 하자.

위의 소스처럼, String.IsNullOrEmpty(string) 메서드를 이용해 넘어온 "n"값이 있는지 확인한다. 그리고 넘어왔다면 무조건 수정기능이므로 클래스 변수로 지정한 IsEditMode를 true로 변경시키자. 다른 메서드인 글쓰기 버튼 이벤트에서 사용하기 위해 클래스 선으로 정의해 놓은 것이다.

이제 할 일은 넘어온 "n"값, 글번호로 기존의 DB 테이블 자료를 가져와서 사용자가 수정할 수 있게 제목,내용에 값을 넣어주는 것이다. 문제는 "첨부파일"인데, 기존에 첨부파일이 있을 수도 있고, 없을 수도 있다. 업로드를 하지 않으면 DB의 해당 file_attach 컬럼값은 (null)이 아닌 공백('')이다. 어떻게 해야 사용자들이 헷갈리지 않게 수정기능을 사용할 수 있을지는 프로그램 기획자의 몫이다. 지금은 우리들이 직접 기획, 디자인, 개발 모두를 하고 있으니 우리들 마음이다. ^^

이렇게 하기로 하자. 파일 업로드는 기존의 첨부에 상관없이 무조건 할 수 있도록 하고, 파일을 첨부한다면 무조건 엎어버리도록 한다. 그러나 파일을 첨부하지 않았다면 기존의 첨부된 파일은 그대로 유지해야 되기 때문에 '기존에 첨부된 파일이 있고, 파일이 새로 첨부되지 않은 상태로 수정' 이라는 조건에 집중하도록 한다.

구현해보자.



먼저 디자인단에 Literal 웹폼을 하나 추가한다(id=liUpload) 이는 수정모드일 때 기존 첨부파일이 있는지 알려주기 위해 만든 것이며, Literal 은 렌더링 결과가 없는 빈 컨트롤이다. Label 컨트롤을 쓰더라도 상관 없으나 불필요한 <span> 태그가 달릴 것이다.




앞서 말했지만 기존 파일 첨부에 따라서 처리방법이 달라지므로 10번째 줄처럼 string 형의 AttachedFile 변수를 추가했다. 전체적으로 board_write.aspx 는 '수정모드'인지 체크하고, 수정모드라면 수정할 수 있는 값들을 불러와서 텍스트 박스에 뿌려준다. 그리고 기존에 첨부된 파일이 있다면 '첨부파일 있음'이라고 표시하는 기능까지가 처음 페이지가 실행될 때 확인할 것들이다.



위의 그림은 글쓰기 페이지가 수정모드로 변한 결과이다. 아차! 하단에 "글쓰기"를 "수정완료" 정도로 바꿔주도록 하자.


페이지의 타이틀 따위를 만들지 않았기 때문에 버튼 말고는 다른 변경사항이 없을 듯 하다. 이제 사용자가 글을 수정한 후에는 기존의 글쓰기(지금의 수정완료) 버튼을 클릭해서 btnWrite_Click() 이벤트를 실행하게 된다. 

이제 글수정 처리전에 Board.cs 에 수정기능의 메서드를 추가하자. 메서드명은 Modify(), 리턴은 없다. 필요한 인수값은 수정한 글 번호(int number), 사용자가 입력한 제목(string title), 내용(string content), 첨부파일명(string upload_file) 이렇게 4개만 필요할 것 같다. 그리고 이를 UPDATE 쿼리문으로 잘 요리하자.



이제 이것을 적용하자.

기존의 글쓰기 이벤트에서는 먼저 첨부파일을 처리하는데, 파일이 있다면 저장을 하고 파일명을 upload_file 변수에 넣어놓게 된다. 만약 없다면 빈 값이 들어가 있게 되며 그대로 테이블에 이것을 저장한다.

수정기능에서는 앞서 말한 것 처럼, 수정기능에서 업로드가 없을 때도 기존의 파일이 있는지 확인해서 유지해야되기 때문에 체크를 해야한다. 다른 기능은 글쓰기와 모두 동일하다.


103번째 줄 처럼 else { .. } 가 추가되었다. 파일이 없어도 Page_Load() 에서 저장한 AttachFile 을 체크해서 기존 첨부가 있다면 upload_file 변수에 그대로 넣어준다.


최종적으로 데이터가 저장될 때는 수정모드는 따로 처리해야 하므로 IsEditMode 를 체크해서 수정모드라면 수정하는 메서드를 호출한 후, 글보기로 이동한다.

이제 수정기능을 실행해보자. /board_write.aspx?c=test&n=글번호 형식으로 페이지를 열고 제목, 내용을 수정한 후 저장해보자. 아마 원하는대로 작동이 안될 것이다.

예전에 "댓글쓰기"기능을 기억하는가? 그 때처럼 지금 글 수정 기능에서는 Page_Load() 에서는 기존의 자료를 불러온다. 그리고 버튼을 클릭하면 버튼의 클릭 이벤트가 먼저 실행되는게 아니라 Page_Load() 가 먼저 실행 후 클릭 이벤트 메서드가 실행이 된다. 이러한 이유로 우리가 글을 수정을 아무리 하더라도 Page_Load() 에서는 기존의 DB값을 다시 불러오게 된다. 그렇게 되면 입력이 아무 의미가 없어지게 된다.

그래서 IsPostBack 을 이용해야 한다. 처음 열렸을 때만 기존의 자료를 불러오도록 처리하자.


이렇게 되면, "글수정"버튼으로 인한 PostBack 이 일어날 때, 다시 기존의 자료를 DB로부터 가져오는 현상을 방지할 수 있을 것이다. 다시 글을 수정해보자. 이제 원하는대로 잘 되는 것을 확인할 수 있다.

문제점은 하나 더 있는데, 기존의 첨부파일을 체크해봐야 클래스 수준에서 정의한 변수string AttachedFile 값은 언제나 공백이다. 왜냐면 이는 IsPostBack 과 상관없이 무조건 변수로 선언되어야 하는 녀석이기 때문이다. Page_Load() 에서 기존의 첨부파일을 유지해봐야 의미가 없다. 그래서 이것은 수정기능의 메서드에서 처리해야된다. 그러면 DB로부터 자료를 한번 더 가져와야된다는 말인데, 그렇게 하지말고 간단하게 폼태그의 Hidden 값을 주어 여기에 넣어놓도록 하자. 이 값은 <form>..</form>에 들어있으므로 ViewState 에 함께 실어서 전송될 것이다.

기존의 코드에서, <form runat="server"> 밑쪽에 <input type="hidden" runat="server" /> 를 하나 넣자. ID는 hdnFile 로 지정하기로 한다.


여기에 값을 유지시켜놓으면 버튼 이벤트에서 hdnFile.Value 속성으로 읽어올 수 있을것이다.



위의 소스처럼 hdnFile에 값을 넣는 코드도 추가한다. (56번째 줄)


마지막으로 수정하기 클릭 이벤트에서 첨부파일 체크하는 부분을 hdnFile.Value 로 컨트롤한다.
이제 기존에 파일 첨부가 있는 글을 수정해보자. 물론 첨부파일은 비워두고 수정한다. 수정시에 첨부파일을 넣지 않았을 때 기존의 첨부파일이 유지되는 것을 볼 수 있다.

좀 복잡해 보이긴 하나 전체적인 의미를 잘 파악하시길 바란다.


구현이 끝났으므로 이제 board_view.aspx 에 있는 "수정하기"버튼 이벤트에다 수정기능 이동 코드를 넣자.



글 삭제 기능은 다음시간에 구현하기로 한다. 직접 미리 해보시길 바란다. 별 어려움 없을 것이다. 그저 현재 글 번호로 DELETE 쿼리문을 이용해 삭제해버리고 리스트로 이동하면 끝나는 기능일 뿐이다. 아.. 그 전에 현재 글에 달린 댓글을 먼저 지우도록 하자. 글이 없으니 댓글도 역시 날려줘야 될 것이다.


다음시간에..

0 Comments
댓글쓰기 폼