这里主要说明,前台绑定数据的玩法,和基本连接数据库的方法(之后会写博客系统详细记录ADO.NET数据的操作)以及Repeater控件的玩法,因此就不按照软件工程的流程写了(按照软件工程流程的项目之后也会写出来)。
留言簿的功能:
1 用户留言
2 显示用户留言
3 管理员处理留言(删除和回复留言)
一 创建数据库
USE [Guid]
GO
CREATE TABLE [dbo].[tb](
[ID] [int] IDENTITY(1,1) NOT NULL,
[UserName] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[PostTime] [datetime] NULL,
[Message] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[IsReplied] [bit] NULL,
[Reply] [varchar](40) COLLATE Chinese_PRC_CI_AS NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
1实现用户留言功能 :Default.aspx 添加用户名和密码的控件以及提交留言的按钮
这里控件的名字尽量要有意义,增强代码的可读性,比如 textbox1命名为“txtName”。
这时就要添加点击button的事件,在Default.aspx.cs:
protected void btnSubmitMsg_Click(object sender, EventArgs e)
{
string conn = System.Configuration.ConfigurationManager.ConnectionStrings["GuidConnectionString"].ToString();
SqlConnection sqlCon = new SqlConnection(conn);
string sqlStr = @"insert into tb (UserName,PostTime,Message,IsReplied,Reply) values('" + this.txtName.Text + "','" + System.DateTime.Now + "','" + this.txtMessage.Text + "',0,'')";
//不使用@,就要把\ 改写为\\,\为转义字符,用@则取消转义
SqlCommand sqlCmd = new SqlCommand(sqlStr, sqlCon);
sqlCon.Open();
int i = sqlCmd.ExecuteNonQuery();
sqlCon.Close();
if (i > 0)
Response.Write("");
else
Response.Write("there are some errors");
BindData();
}
1 )获得数据库连接字符串
2 )建立数据库连接
3 )建立要执行的Sql语句
4 )打开带有要执行Sql语句的连接
5 )执行Sql语句
6 )关闭连接,有的返回信息,有的不用返回。
这样用户发表留言就ok了
2 显示用户留言
这里用到了数据源控件——repeater。将repeater控件拖拽到aspx页面上,其实在aspx源代码页自己打代码会更方便些。我刚开始学习ASP.NET的时候觉得拖拽控件很方便,
但是现在更喜欢直接在源代码里面敲代码,因为拖拽控件设置属性还要在属性框里面找,不如自己需要什么属性就敲哪个属性来的快。
<
<%#Eval("Message")%>
<%#Eval("PostTime")%>-<%#Eval("UserName")%>
管理员回复:<%#Eval("IsReplied").ToString()=="false"?"暂无":Eval("Reply") %>
前台绑定数据:
public void BindData()
{
string conn = System.Configuration.ConfigurationManager.ConnectionStrings["GuidConnectionString"].ToString();
SqlConnection sqlCon = new SqlConnection(conn);
string sqlStr = "select * from tb";
SqlDataAdapter sda = new SqlDataAdapter(sqlStr, sqlCon);
DataSet ds = new DataSet();
sda.Fill(ds, "tb");
rptShowMsg.DataSource = ds.Tables["tb"];
rptShowMsg.DataBind();
}
这里用到了DataAdapter,DataSet,DataTable.ADO.NET稍后会写出来。
简单说一下DataSet可以想成是内存中的库,DataTable则是内存中的表,DataAdapter就是“桥”的作用,将数据库和内存中“库”连起来
具体步骤:
1 )获得数据库连接字符串
2 )建立数据库连接
3 )建立要执行的Sql语句
4 )建立Adapter,类似SqlCommand。
5 )建立Dataset,
6)将Adapter获得的数据信息填充dataset
7)数据源控件(这里是repeater,ID="rptShowMsg")绑定数据。
* dataset填充之后,绑定数据的时候是以“表”为单位的。
当打开页面,用户的留言就应该显示出来,而且,当用户添加一条留言提交之后也应该看到新留言。
因此BindData()应该放在page_load()方法里面,同时放在button事件里面。后台完整代码:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Data.Sql;
using System.Data.SqlTypes;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindData();
}
}
protected void btnSubmitMsg_Click(object sender, EventArgs e)
{
string conn = System.Configuration.ConfigurationManager.ConnectionStrings["GuidConnectionString"].ToString();
SqlConnection sqlCon = new SqlConnection(conn);
string sqlStr = @"insert into tb (UserName,PostTime,Message,IsReplied,Reply) values('" + this.txtName.Text + "','" + System.DateTime.Now + "','" + this.txtMessage.Text + "',0,'')";
//不使用@,就要把\ 改写为\\,\为转义字符,用@则取消转义
SqlCommand sqlCmd = new SqlCommand(sqlStr, sqlCon);
sqlCon.Open();
int i = sqlCmd.ExecuteNonQuery();
sqlCon.Close();
if (i > 0)
Response.Write("");
else
Response.Write("there are some errors");
BindData();
}
public void BindData()
{
string conn = System.Configuration.ConfigurationManager.ConnectionStrings["GuidConnectionString"].ToString();
SqlConnection sqlCon = new SqlConnection(conn);
string sqlStr = "select * from tb";
SqlDataAdapter sda = new SqlDataAdapter(sqlStr, sqlCon);
DataSet ds = new DataSet();
sda.Fill(ds, "tb");
rptShowMsg.DataSource = ds.Tables["tb"];
rptShowMsg.DataBind();
}
}
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
无标题页
3 管理员处理留言(增删查改)
当管理员以username=admin password=admin 登录的话 ,就可以对留言进行操作。这里管理员登录就不Query DB了。
管理员一旦登录进去的话,之前隐藏的Panel就可视化,留言就显示出来。
adminLogin.aspx代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="adminLogin.aspx.cs" Inherits="adminLogin" %>
无标题页
在这个repeater中我们添加了2个功能:删除留言、发表回复。这2个功能Button都是在repeater中的,点击button就会触发repeater的
命令事件,
删除操作属于“Delete”,发表回复属于“Update”,数据删除更新需要Where条件,
因此我们用主键ID作为条件,以删除操作为例:命令名称: CommandName="deleteMsg" 条件参数:CommandArgument='<%# Eval("ID") %>'
❀“条件参数”说明:前台绑定的数据,不仅能后台向前台绑定,也可以前台向后台传数据。
❀后台向前台绑定数据:就是之前所说的BindData()方法,绑定ID,留言内容等
数据库中拿到数据之后,前台Eval自动绑定对应字段。
❀前台向后台传数据:删除或更新留言,则是通过刚刚绑好的ID,带着要回复留言的内容,去后台走DB【回复留言可以不绑定:Text='<%# Eval("Reply") %>',不绑定的话,点击发表回复,回复内容在adminLogin.aspx中就看不到,但是在default页面可以刷新看到,因为default页面绑定了Reply-<%#Eval("IsReplied").ToString()=="false"?"暂无":Eval("Reply") %>】
adminLogin.aspx.cs代码:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;
public partial class adminLogin : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// BindData();
}
protected void btnLogin_Click(object sender, EventArgs e)
{
if ((this.txtName.Text == "admin") && (this.txtpwd.Text == "admin"))
{
BindData();
this.Panel1.Visible = true;
}
}
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
string conn = System.Configuration.ConfigurationManager.ConnectionStrings["GuidConnectionString"].ToString();
SqlConnection sqlCon = new SqlConnection(conn);
if (e.CommandName == "deleteMsg")
{
string sqlStr = "delete from tb where ID="+ e.CommandArgument+"";
SqlCommand cmd = new SqlCommand(sqlStr, sqlCon);
sqlCon.Open();
int i=cmd.ExecuteNonQuery();
sqlCon.Close();
if (i > 0)
Response.Write("");
else
Response.Write("");
BindData();
}
if (e.CommandName == "sendReply")
{
string strSql="update tb set IsReplied=1 ,Reply='"+((TextBox)e.Item.FindControl("txtReply")).Text+"'where ID="+e.CommandArgument+"";
sqlCon.Open();
SqlCommand cmd = new SqlCommand(strSql, sqlCon);
int i = cmd.ExecuteNonQuery();
sqlCon.Close();
if (i > 0)
Response.Write("");
else
Response.Write("");
BindData();
}
}
public void BindData()
{
string conn = System.Configuration.ConfigurationManager.ConnectionStrings["GuidConnectionString"].ToString();
SqlConnection sqlCon = new SqlConnection(conn);
string sqlStr = "select * from tb order by PostTime DESC";
SqlDataAdapter sda = new SqlDataAdapter(sqlStr, sqlCon);
DataSet ds = new DataSet();
sda.Fill(ds, "tb");
Repeater1.DataSource = ds.Tables["tb"];
Repeater1.DataBind();
}
}
说明的是:
❀e.CommandName == "sendReply"//如果repeater中的命令式"sendRely",走下面的方法体
❀Reply='"+((TextBox)e.Item.FindControl("txtReply")).Text//在repeater中找到控件类型是TextBox,控件TextBox ID="txtReply"的控件,并获取他的Text属性值