6.数据库——新闻管理系统管理页面
adminCate.aspx
页面代码:
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
类别名称:<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="添加类别" onclick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="用来显示信息"></asp:Label>
</asp:Content>
//引用访问数据库命名空间 using System.Data; using System.Data.SqlClient; /*首先设置一个字符串,在C#中叫数据库连接字符串 一般ASP.Net当中将其放在web.config文件当中 <connectionStrings> <add name="SQLSERVERCONNECTIONSTRING" connectionString=" Data Source= 192.168.43.1;Initial Catalog= dotnet;User ID= dotnet;Password=dotnet " providerName="System.Data.SqlClient"/> </connectionStrings> 然后可以在应用程序中调用: string conString = ConfigurationManager.ConnectionStrings["SQLSERVERCONNECTIONSTRING"].ConnectionString; 与下面这条语句的作用相同。 */ string conString2 = "Data Source= 192.168.43.1;Initial Catalog= dotnet;User ID= dotnet;Password=dotnet"; //新建一个SqlServer连接。注意,在创建时可以在构造函数中传递参数(连接字符串) SqlConnection myConnection = new SqlConnection(conString2); //准备一个将要执行的语句。 string cmdText = "Insert into cate values('" + TextBox1.Text + "')"; //新建一个SqlServer命令行对象,将SqlServer连接对象和将要执行的语句字符串传给他。 SqlCommand myCommand = new SqlCommand(cmdText, myConnection); //然后打开数据库连接 myConnection.Open(); //执行SqlServer命令行对象的ExecuteNonQuery()将返回受影响的行数。 int lines = myCommand.ExecuteNonQuery(); if(lines > 0) Label1.Text = "类别[" + TextBox1.Text + "]添加成功"; //最后关闭数据库连接 myConnection.Close();
Admin_News.aspx:
需要实现的内容:
1)类别自动读取数据库中Cate表中的内容,并且插入到下拉菜单DropDownList当中,并且它在页面上显示的文本是CateName而后台可以读取到选中类别的CateID就是选中项的真实Value。
2)新闻内容用富文本编辑器实现,可以方便用户修改。
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<table>
<tr>
<td >书名[Title]</td>
<td>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td>作者[Author]</td>
<td>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td>内容[Contents]</td>
<td>
<asp:TextBox ID="TextBox3" runat="server" Height="257px" TextMode="MultiLine"
Width="395px"></asp:TextBox></td>
</tr>
<tr>
<td>类别[CateID]</td>
<td>
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
</td>
</tr>
<tr>
<td>出版时间[PostDate]</td>
<td>
<asp:TextBox ID="TextBox4" runat="server"></asp:TextBox></td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="插入" onclick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</asp:Content>
首先是填充DropDownList(下拉列表)中的内容:
protected void Page_Load(object sender, EventArgs e) { string conString2 = "Data Source= 192.168.43.1;Initial Catalog= dotnet;User ID= dotnet;Password=dotnet"; SqlConnection myConnection = new SqlConnection(conString2); string cmdText = "select * from Cate"; SqlCommand myCommand = new SqlCommand(cmdText, myConnection); myConnection.Open(); //注意这里通过调用myCommand.ExecuteReader()得到了SqlServer数据读取者对象,它可以读取查询到的内容。 SqlDataReader dr = myCommand.ExecuteReader(); while (dr.Read()) { string catename = dr["catename"].ToString(); string cateid = dr["cateid"].ToString(); //注意这行语句实现了向下拉列表框插入新项 DropDownList1.Items.Add(new ListItem(catename, cateid)); } } protected void Button1_Click(object sender, EventArgs e) { string conString2 = ConfigurationManager.ConnectionStrings["SQLSERVERCONNECTIONSTRING"].ConnectionString; SqlConnection myConnection = new SqlConnection(conString2); SqlCommand myCommand = new SqlCommand(); myCommand.Connection = myConnection ; myConnection.Open(); /* 说明:这里用到了一种新的处理数据库数据修改的不安全性的技术,规避了嵌入式SQL攻击, 数据库命令的安全性 Select 最安全不会对数据库执行更改 Insert 排第二,数据只增加不减少。 Update 和 Delete 最不安全,数据会丢失。要求跟Where 一起使用。 比如我们向刚刚的adminCate.aspx页面的文本框中插入如下内容 myCateValue');Drop Table News;Insert into cate (catename) values('aa 在后台执行的将会是Insert into cate values('" + TextBox1.Text + "') 就是Insert into cate values('myCateValue');Drop Table News;Insert into cate (catename) values('aa'); 其实这行语句由三部分组成中间那部分将对数据库表执行删除操作。 如何让这条危险的语句失效呢?下面就提供了一种方法,当然也可以使用Sql存储过程实现 */ //首先在语句中Values后面的真实内容都用“@变量名”代替 myCommand.CommandText = "Insert into [News] ([Title],[Author],[Contents],[CateID],[PostDate]) values(@Title,@Author,@Contents,@CateID,@PostDate)"; //通过myCommand.Parameters.Add()方法确定他们的类型 myCommand.Parameters.Add("@Title", SqlDbType.NVarChar, 50); //利用各个文本框中的值对实际参数赋值时,C#将替我们检查变量内容是否符合变量类型定义。 myCommand.Parameters["@Title"].Value = TextBox1.Text; myCommand.Parameters.Add("@Author", SqlDbType.NVarChar, 50); myCommand.Parameters["@Author"].Value = TextBox2.Text; myCommand.Parameters.Add("@Contents", SqlDbType.NVarChar, 500); myCommand.Parameters["@Contents"].Value = TextBox3.Text; myCommand.Parameters.Add("@CateID", SqlDbType.Int); myCommand.Parameters["@CateID"].Value = DropDownList1.SelectedValue; myCommand.Parameters.Add("@PostDate", SqlDbType.DateTime); myCommand.Parameters["@PostDate"].Value = TextBox4.Text; int isInserted = myCommand.ExecuteNonQuery(); if (isInserted > 0) Label1.Text = "类别[" + TextBox1.Text + "]添加成功"; else Label1.Text = "添加失败"; myConnection.Close(); }
然后,我将插播一个关于SqlAdapter对象(中间件)来执行数据库命令的知识。
大家知道,以下代码是可以实现一条信息的插入的:
String conString = "data source=192.168.43.1;user id=dotnet;pwd=dotnet;database=dotnet"; SqlConnection myConnection = new SqlConnection(conString); string cmdText = "Insert into cate values('" + TextBox1.Text + "')" ; myConnection.Open(); SqlCommand mycommand = new SqlCommand(cmdText, myConnection); int isok = mycommand.ExecuteNonQuery(); if (isok > 0) Response.Write(isok + "行受影响"); myConnection.Close();
其实SqlAdapter对象可以提供更好的交互性能,且更加安全。
SqlConnection myConnection = new SqlConnection(conString2); string cmdText = "Select top 10 * From cate"; SqlDataAdapter da = new SqlDataAdapter(cmdText, myConnection); SqlCommandBuilder builder = new SqlCommandBuilder(da); DataSet ds = new DataSet(); da.Fill(ds,"cate"); ds.Tables[0].Rows[0]["CateName"] = "jiowjdf"; ds.Tables[0].Rows.Add(1, "bbb"); da.Update(ds,"cate");
Update()不执行是不会改变数据库中的实际内容的。也就是说其它用户在我的页面脚本没有执行Update()前是看不到我对数据库做的修改,但是我却可以通过DataAdapter查看到。可以很快想到,上面的语句的应用将十分便捷和安全,比如DataSet作为了一个GridView的数据源与其绑定,用户在GridView里面改动了表中某条记录,但是或许我们为了减少数据库的读写次数,或者对其是否会破外数据库进行安全性的输入检查我们就可以用DataAdapter这个中间件暂存下,等我们确认数据都正确且用户改动完毕后执行Update将数据改动提交到数据库,这样是不是遵循了一种最佳的实践?
当然,SqlDataAdapter也拥有像SqlCommand对象同样的执行语句的功能。
SqlDataAdapter da2 = new SqlDataAdapter("select * from Cate", myConnection); da2.UpdateCommand = new SqlCommand("Update Cate Set CateName=@Name where CateID=@ID"); //定义Name参数,对应于Cate表的CateName列 da.UpdateCommand.Parameters.Add("@Name", SqlDbType.VarChar, 50, "CateName"); //ID参数对应Cate表CateID列,它是修改前的原值 SqlParameter parameter = da.UpdateCommand.Parameters.Add("@ID", SqlDbType.Int); parameter.SourceColumn = "CateID"; parameter.SourceVersion = DataRowVersion.Original; DataSet ds3 = new DataSet(); //用Fill方法返回的数据,填充DataSet,数据表取名tempCate da2.Fill(ds3, "tempCate"); //将数据表tempCate数据复制到DataTable对象 DataTable dt3 = ds3.Tables["tempCate"]; //从DataRowCollection中遍历取出各行DataRow foreach(DataRow dtr in dt3.Rows) { //对每个类别的CateName后加上A dtr[1] = dtr[1] + "A"; } //提交更新 da2.Update(ds3, "tempCate");
最后,就是富文本编辑器,这里用到了kindeditor,可以直接去网上下载,然后解压出来文件夹直接放到网站根目录下, 加入如下代码,就OK
<script>
var editor;
KindEditor.ready(function (K) {
editor = K.create('#ctl00_ContentPlaceHolder1_TextBox3');
});
</script>
注意到内容对应的文本框叫TextBox3,但是打开浏览器却不是了,就是因为应用模板页的缘故。
<td>内容[Contents]</td>
<td>
<asp:TextBox ID="TextBox3" runat="server" Height="257px" TextMode="MultiLine"
Width="395px"></asp:TextBox></td>