ASP.NET 기본 게시판
web.config
<?xml version="1.0"?>
<!--
ASP.NET 응용 프로그램을 구성하는 방법에 대한 자세한 내용을 보려면
http://go.microsoft.com/fwlink/?LinkId=169433 을 방문하십시오.
-->
<configuration>
<connectionStrings>
<add name="conStr" connectionString="server=localhost;database=ASPNET;uid=sa;pwd=zangna1" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<httpRuntime requestValidationMode="2.0"/>
<pages theme="basic"/>
</system.web>
<system.webServer>
<defaultDocument>
<files>
<add value="Board.aspx"/>
</files>
</defaultDocument>
</system.webServer>
</configuration>
1. 첫째로 어떤페이지에서든 상단 하단 메뉴를 나누어 사용할수 있게마스터 페이지를 생성한다.
Board.master
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Board.master.cs" Inherits="Board" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
<style type="text/css">
.style1
{
width: 100%;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div id="header">
<table class="table" style="width:100%;">
<tr>
<td>첫번째 메뉴</td>
<td>두번째 메뉴</td>
<td>세번째 메뉴</td>
<td>네번째 메뉴</td>
</tr>
</table>
</div>
<div style="text-align:center; margin:20px;">
<img src="images/title.gif" alt="게시판" />
</div>
<div id="content">
<%--모든페이지들을 상속받기 위해서 선언 ContentPlaceHolder 사용--%>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
<div id="footer">
<hr style="width:650px; border-top:1px solid #003300" />
<div style="text-align:center;padding:10px;">
©Copyright 2012 Test.com All rights reserved.
</div>
</div>
</form>
</body>
</html>
2. 전체적인 스타일을 정하여 새로만들기 asp.net폴더 생성후 Theme 선택 하여 css 파일을 생성한다. webconfig에서 디폴트로 css 파일을 지정해 줄수 있다. 그러면 어떤 페이지에서든 css가 적용된다.
/* board.css */
body, table, td, p, div, span, input, textarea, a, select
{
font-size:12px;
font-family:돋움;
color:#343434;
line-height:1.4em;
}
a {text-decoration:none;}
a:hover {color:Red;}
/* 텍스트박스 종류 */
.txt {border:1px solid #333333;}
/* 테이블 */
.table {border:1px solid #222222; border-collapse:collapse;}
.table td, .table th {border:1px solid #222222; padding:3px;}
.table td {background-color:Silver;}
/* 테이블(추가) */
/* 전체 레이아웃 */
/* 테이블 td에 딱 붙이기 위해서 사용 */
body {margin:0px;}
#header
{
width:100%;
}
#content
{
width:650px;
margin:0px auto;
/*내용물이 늘어나도 테이블 안쪽에서 유지됨 */
min-height:350px;
}
#footer
{
width:650px;
margin-top:15px;
margin:0px auto;
}
페이지는 모두 마스터 페이지를 참조한다.
List.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Board.master" AutoEventWireup="true" CodeFile="List.aspx.cs" Inherits="List" Trace="true" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div style="text-align:center;margin:10px;">
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AutoGenerateColumns="False" DataKeyNames="seq" DataSourceID="SqlDataSource1"
onrowdatabound="GridView1_RowDataBound" Width="600px">
<Columns>
<asp:BoundField DataField="seq" HeaderText="번호" InsertVisible="False"
ReadOnly="True" SortExpression="seq">
<ItemStyle HorizontalAlign="Center" Width="50px" />
</asp:BoundField>
<asp:HyperLinkField DataNavigateUrlFields="seq"
DataNavigateUrlFormatString="View.aspx?seq={0}" DataTextField="subject"
HeaderText="제목">
<ItemStyle Width="330px" />
</asp:HyperLinkField>
<asp:BoundField DataField="name" HeaderText="이름" SortExpression="name">
<ItemStyle HorizontalAlign="Center" Width="80px" />
</asp:BoundField>
<asp:BoundField DataField="regDate" DataFormatString="{0:yyyy-MM-dd}"
HeaderText="날짜" SortExpression="regDate">
<ItemStyle HorizontalAlign="Center" Width="80px" />
</asp:BoundField>
<asp:BoundField DataField="readCount" HeaderText="읽음"
SortExpression="readCount">
<ItemStyle HorizontalAlign="Center" Width="50px" />
</asp:BoundField>
</Columns>
<HeaderStyle BorderStyle="Solid" BorderWidth="1px" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:conStr %>"
SelectCommand="SELECT [seq], [name], [subject], [readCount], [regDate], [email] FROM [Board] ORDER BY [regDate] DESC">
</asp:SqlDataSource>
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/images/write.gif"
onclick="ImageButton1_Click" />
</div>
</asp:Content>
List.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
public partial class List : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//조회수 증가용 쿠키 할당 쿠키가 n일경우 무조건 카운트 증가 준비 완료~
Response.Cookies["read"].Value = "n";
GridView1.EmptyDataText = "해당 게시판의 게시된 글 내용이 없습니다.";
}
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
Response.Redirect("Add.aspx");
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//헤더는 제외하고 현재 이벤트 발생이 내가 바인딩된 타입이냐?
//if(!ispostback) 과 비슷하게 무조건 사용하자.
//e.Row = 한행이라는 뜻이며 GrideViewRow x5개 Trace키면 보이는 추적페이지에서 각셀들에 대한정보가 있으며 이러한 것들은 배열로 관리된다.
//1. 제목이 길면.. 자르기
HyperLink subject = e.Row.Cells[1].Controls[0] as HyperLink;
if (subject.Text.Length > 20)
{
subject.Text = subject.Text.Substring(0, 20) + "...";
}
//2. 글쓴지 일정시간이지나면.. New.gif 표시 30분 이내에 쓴글
//Response.Write(e.Row.Cells[3].Text + "<br />");
//현재 바인딩되거나 바인딩된 데이터에 접근하는 방법
//A. 출력된 결과값에 접근하는 방법
//바운드된 필드(셀을 뒤지면 언제든지 출력된 결과를 가져올수 있다.)
//Response.Write(e.Row.Cells[2].Text);
//B. (출력과 상관없이) 바인딩되는 원본에 접근하는 방법
//전제 조건은 데이터 원본(쿼리문 실행된 값이 있어야 한다.) 화면상에 안보여도 상관없다.
//데이터원본(seq,subject,name, regDate, readCount, email)
//e.Row = 실제눈에보이는 게시판에 한줄 (출력된 행)
//그행을 만드는 사용된 실제 레코드이다.(데이터 원본 레코드)
DataRowView row = e.Row.DataItem as DataRowView;
//Response.Write(row["regDate"].ToString());
DateTime regDate = (DateTime)row["regDate"];
//현재시간에서 글쓴시간 빼기
TimeSpan gap = DateTime.Now - regDate;
if (gap.TotalMinutes <= 30)
{
//30분 이내에 쓴글
//e.Row.Cells[1]
//타입을 맞추기위해 스트링 형태를 컨트롤 형태로 변환하기 위해 사용한다.
LiteralControl img = new LiteralControl("<img src='images/new.gif' alt='새글' style='margin-left:5px;' />");
e.Row.Cells[1].Controls.Add(img);
//e.Row.Cells[1].Controls.AddAt(0, img);
}
}
}
}
Add.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Board.master" AutoEventWireup="true" CodeFile="Add.aspx.cs" Inherits="Add" ValidateRequest="false" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" runat="server"
contentplaceholderid="ContentPlaceHolder1">
<table class="table" style="width:600px;">
<tr>
<td align="center" bgcolor="Silver" width="150">
이름</td>
<td width="450">
<asp:TextBox ID="TextBoxName" runat="server" CssClass="txt" Width="100px"></asp:TextBox>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
이메일</td>
<td width="450">
<asp:TextBox ID="TextBoxEmail" runat="server" CssClass="txt" Width="250px"></asp:TextBox>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
제목</td>
<td width="450">
<asp:TextBox ID="TextBoxSubject" runat="server" CssClass="txt" Width="95%"></asp:TextBox>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
내용</td>
<td width="450">
<asp:TextBox ID="TextBoxContent" runat="server" CssClass="txt" Height="150px"
TextMode="MultiLine" Width="95%"></asp:TextBox>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
태그적용</td>
<td width="450">
<asp:CheckBox ID="CheckBoxTag" runat="server" Text="HTML 태그 적용함" />
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
암호</td>
<td width="450">
<asp:TextBox ID="TextBoxPwd" runat="server" CssClass="txt" TextMode="Password"
Width="100px"></asp:TextBox>
</td>
</tr>
</table>
<div style="text-align:center;margin:10px;">
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/images/list.gif"
onclick="ImageButton1_Click" ValidationGroup="list" />
<asp:ImageButton ID="ImageButton2" runat="server" ImageUrl="~/images/write.gif"
onclick="ImageButton2_Click" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
ControlToValidate="TextBoxName" Display="None" ErrorMessage="이름을 입력하세요!"
SetFocusOnError="True"></asp:RequiredFieldValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server"
ControlToValidate="TextBoxEmail" Display="None" ErrorMessage="제목을 입력하세요"
SetFocusOnError="True"></asp:RequiredFieldValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server"
ControlToValidate="TextBoxSubject" Display="None" ErrorMessage="내용을 입력하세요"
SetFocusOnError="True"></asp:RequiredFieldValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server"
ControlToValidate="TextBoxPwd" Display="None" ErrorMessage="암호를 입력하세요"
SetFocusOnError="True"></asp:RequiredFieldValidator>
<asp:ValidationSummary ID="ValidationSummary1" runat="server"
ShowMessageBox="True" ShowSummary="False" />
</div>
</asp:Content>
Add.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
public partial class Add : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
//List
Response.Redirect("List.aspx");
}
protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
{
//Write
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["conStr"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "INSERT INTO Board (name, email, subject, content, tag, pwd, userIP) VALUES (@name, @email, @subject, @content, @tag, @pwd, @userIP)";
//매개변수
cmd.Parameters.Add("@name", SqlDbType.NVarChar, 20);
cmd.Parameters.Add("@email", SqlDbType.VarChar, 50);
cmd.Parameters.Add("@subject", SqlDbType.NVarChar, 100);
cmd.Parameters.Add("@content", SqlDbType.NVarChar, 3000);
cmd.Parameters.Add("@tag", SqlDbType.Char, 1);
cmd.Parameters.Add("@pwd", SqlDbType.VarChar, 20);
cmd.Parameters.Add("@userIP", SqlDbType.VarChar, 15);
//값
cmd.Parameters["@name"].Value = TextBoxName.Text;
cmd.Parameters["@email"].Value = TextBoxEmail.Text;
cmd.Parameters["@subject"].Value = TextBoxSubject.Text;
cmd.Parameters["@content"].Value = TextBoxContent.Text;
cmd.Parameters["@tag"].Value = CheckBoxTag.Checked ? "y" : "n";
cmd.Parameters["@pwd"].Value = TextBoxPwd.Text;
cmd.Parameters["@userIP"].Value = Request.UserHostAddress;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
string script = @"<script type='text/javascript'>
alert('글쓰기 완료!!');
location.href = 'List.aspx';
</script>";
this.ClientScript.RegisterClientScriptBlock(this.GetType(), "add", script);
}
}
View.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Board.master" AutoEventWireup="true" CodeFile="View.aspx.cs" Inherits="View" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<table class="table" style="width:600px;">
<tr>
<td align="center" bgcolor="Silver" width="150">
이름</td>
<td width="450">
<asp:Label ID="LabelName" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
이메일</td>
<td width="450">
<asp:Label ID="LabelEmail" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
제목</td>
<td width="450">
<asp:Label ID="LabelTitle" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150" style="padding:10px;">
내용</td>
<td width="450">
<asp:Label ID="LabelContent" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
번호</td>
<td width="450">
<asp:Label ID="LabelSeq" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
읽음</td>
<td width="450">
<asp:Label ID="LabelReadCount" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
날짜</td>
<td width="450">
<asp:Label ID="LabelDate" runat="server"></asp:Label>
</td>
</tr>
</table>
<div style="text-align:center;margin:10px;">
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/images/list.gif"
onclick="ImageButton1_Click" ValidationGroup="list" style="width: 39px" />
<asp:ImageButton ID="ImageButton2" runat="server"
ImageUrl="~/images/modify.gif" onclick="ImageButton2_Click"
style="width: 39px" />
<asp:ImageButton ID="ImageButton3" runat="server"
ImageUrl="~/images/delete.gif" onclick="ImageButton3_Click" />
</div>
</asp:Content>
View.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
public partial class View : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//seq의 상세보기
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["conStr"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "UPDATE Board SET readCount = readCount + 1 WHERE seq=@seq;";
//같은 번호이기 때문에 파라메터 하나만 던져도 가능하다.
cmd.Parameters.Add("@seq", SqlDbType.Int);
cmd.Parameters["@seq"].Value = Request.QueryString["seq"];
con.Open();
if (Request.Cookies["read"] == null || Request.Cookies["read"].Value == "n")
{
//조회수 증가
cmd.ExecuteNonQuery();
Response.Cookies["read"].Value = "y";
}
cmd.CommandText = "select * from Board where seq=@seq";
//결과값으로 처리용도지만 ExecuteNonQuery 용도로도 사용할수는 있다.
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
//출력
LabelName.Text = string.Format("{0} [{1}]", reader["name"].ToString(), reader["userIP"].ToString());
LabelEmail.Text = reader["email"].ToString();
LabelTitle.Text = reader["subject"].ToString();
//글 내용
string content = reader["content"].ToString();
//\r\n = 엔터값 출력(웹페이지) \r\n 출력 방식이 틀려서 엔터값이 안먹는다.<br />
//DB에는 \r\n으로 들어가 있다. 원본은 회손하지 않고 처리해야 한다.
//엔터값처리 -> <br />
content = content.Replace("\r\n", "<br />");
//태그 적용 안함 처리 ( < - > <)
if (reader["tag"].ToString() == "n")
{
Server.HtmlEncode(content);
}
//<script> 무조건 적용안함
content = content.Replace("<script>", "<script>").Replace("</script>", "</script>");
Response.Write(Request.UserHostAddress);
LabelContent.Text = content;
LabelSeq.Text = reader["seq"].ToString();
LabelReadCount.Text = reader["readCount"].ToString();
LabelDate.Text = reader["regDate"].ToString();
}
reader.Close();
con.Close();
}
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
//List
Response.Redirect("List.aspx");
}
protected void ImageButton3_Click(object sender, ImageClickEventArgs e)
{
//삭제 Del.aspx?seq=5
Response.Redirect("Del.aspx?seq=" + Request.QueryString["seq"]);
}
protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
{
//수정
Response.Redirect("Edit.aspx?seq=" + Request.QueryString["seq"]);
}
}
Del.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Board.master" AutoEventWireup="true" CodeFile="View.aspx.cs" Inherits="View" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<table class="table" style="width:600px;">
<tr>
<td align="center" bgcolor="Silver" width="150">
이름</td>
<td width="450">
<asp:Label ID="LabelName" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
이메일</td>
<td width="450">
<asp:Label ID="LabelEmail" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
제목</td>
<td width="450">
<asp:Label ID="LabelTitle" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150" style="padding:10px;">
내용</td>
<td width="450">
<asp:Label ID="LabelContent" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
번호</td>
<td width="450">
<asp:Label ID="LabelSeq" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
읽음</td>
<td width="450">
<asp:Label ID="LabelReadCount" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td align="center" bgcolor="Silver" width="150">
날짜</td>
<td width="450">
<asp:Label ID="LabelDate" runat="server"></asp:Label>
</td>
</tr>
</table>
<div style="text-align:center;margin:10px;">
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/images/list.gif"
onclick="ImageButton1_Click" ValidationGroup="list" style="width: 39px" />
<asp:ImageButton ID="ImageButton2" runat="server"
ImageUrl="~/images/modify.gif" onclick="ImageButton2_Click"
style="width: 39px" />
<asp:ImageButton ID="ImageButton3" runat="server"
ImageUrl="~/images/delete.gif" onclick="ImageButton3_Click" />
</div>
</asp:Content>
Del.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
public partial class Del : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
//일치한다면 수정 작업 진행
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["conStr"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "SELECT COUNT(*) FROM Board WHERE seq=@seq AND pwd=@pwd";
//같은 번호이기 때문에 파라메터 하나만 던져도 가능하다.
cmd.Parameters.Add("@seq", SqlDbType.Int);
cmd.Parameters["@seq"].Value = Request.QueryString["seq"];
cmd.Parameters.Add("@pwd", SqlDbType.VarChar, 20);
cmd.Parameters["@pwd"].Value = TextBoxPwd.Text;
con.Open();
int result = (int)cmd.ExecuteScalar();
string script = "";
if (result ==1)
{
cmd.CommandText = @"DELETE FROM Board
WHERE seq = @seq";
cmd.ExecuteNonQuery();
script = @"<script type='text/javascript'>
alert('삭제 완료!!');
location.href = 'List.aspx';
</script>";
}
else
{
//아니면 안내메시지 출력
script = @"<script type='text/javascript'>
alert('암호가 일치하지 않습니다!!');
</script>";
}
con.Close();
this.ClientScript.RegisterClientScriptBlock(this.GetType(), "edit", script);
}
protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
{
string script = @"<script type='text/javascript'>
location.href = 'List.aspx';
</script>";
this.ClientScript.RegisterClientScriptBlock(this.GetType(), "edit", script);
}
}