|
本文详细叙述了一个"网站新闻管理系统"的设计思路、开发细节,并公开了程序源代码,在稍加修改的基础上,用户完全能够在极短时间内拥有自己的"网站新闻管理系统"!
一、具有以下特点:
1、可视性:对新闻的处理(包括发布、修改、删除)将立即在主页的对应栏目显示出来,达到"即时发布、即时见效"的功能;
2、功能完善:包括常见网站的新闻(消息)管理的各个方面:新闻发布、浏览、删除、修改、检索等各个方面;完整地实现了网站对即时新闻的管理要求;
3、操作简单、界面友好:完全控件式的页面布局,使你即便不熟悉文字录入,仍可以用拷贝+粘贴的方式录入新闻内容;许多选项包括新闻类别、来源部门等只需要点击鼠标就可以完成;另外,跟踪出现的提示信息也让用户随时清楚自己的操作情况。
4、代码少:新闻录入、更新两大功能使用了同一页面(Write.aspx);新闻浏览、查询输出两大功能也使用了同一页面(View.aspx),极大地减少了程序代码。
5、移植简单:针对不同的企业,只需要修改来源部门名称,就可以开发出适合本企业特点的网站新闻管理系统!
二、开发细节及部分程序代码:
1、构建数据库、表结构
使用sqllserver2000建立以下数据库jxdb,含以下两个数据表:
(1)、数据表News:包含的字段有:编号、姓名、标题,关键字,内容,发布日期,供稿部门和新闻类型,字段说明如下:
Id 编 号 Name 用户姓名 Title 标 题 Keywords 关键字 Type 类 型 Fromwhere 来源部门 Datetime 发布日期
(用户可以根据需要增减)
(2)、数据表Reg:用于记录"注册用户"信息,包括用户名name、密码pwd、性别sex、部门dept等字段,它可以简化到只含两个字段:name和pwd。
字段说明如下:
name 用户名 pwd 密码 email 电子邮件 dept 所属部门 sex 性别 Tel 电话
2、程序实现:
由于需要在页面之间传值,跟asp中一样,程序中使用了索引字符串传递参数,并在目标页面(一般通过target指定)中通过Request["索引串名"]取得参数值;另外,Visual C#中的静态(static)变量只属于类所有,声明类的实例并不改变它的值,所以在几个页面中也使用了全局静态变量来实现了更强大的功能,即任何页面(而不需要指定目标页面)可以通过类名取得该值(比如任何页面可以通过string id=Manage.Id取得类Manage 中静态变量Id的值)。
另外,为充分利用Visual Studio.Net集成开发环境的强大功能,程序中也多处用到了Asp.net的数据显示控件DataGrid、DataView等,对数据库的操作更是涉及到了Ado.net的各个方面,包括插入(insert),删除(delete),更新(updage)及检索(select)等,并尽可能用独立的代码来实现,以利于读者引用。
以下分析各页面的实现方法,并就其用到的主要事件/函数进行讲解,另外,打包程序中含有完整的程序代码,他们中有较完整的注释信息,相信读者容易看懂。
(1)、登录页面(Login.aspx):
系统将所有用户分为注册用户和过客两种:
i.注册用户,有新闻录入权限、管理新闻权限。
ii.过客用户,能够进入新闻录入也面,但不具有录入权限;不能进入管理中心。
主要事件/函数有:
//IsRegUserOk函数:判断用户是否已经注册+密码是否正确 public bool IsRegUserOk() { string name=TextBoxName.Text.Trim(); string pwd=TextBoxPassword.Text.Trim(); //建立/打开数据库连接 SqlConnection conn=new SqlConnection(); conn.ConnectionString="server=(local);uid=sa;pwd=;database=jxdb"; conn.Open(); //建立sql字符串 string sql="select * from reg where name='"+name+"'"; SqlDataReader dr; SqlCommand cmd=new SqlCommand(sql,conn); dr=cmd.ExecuteReader(); //保留用户注册与否信息 bool isRegUserExist=dr.Read(); //关闭DataReader dr.Close(); //取得用户名的密码 string sqlBoth="select * from reg where name='"+name+"'"; sqlBoth+="and pwd='"+pwd+"'"; SqlCommand cmdBoth=new SqlCommand(sqlBoth,conn); SqlDataReader drBoth; drBoth=cmdBoth.ExecuteReader(); //保留用户名+密码同时存在信息 bool isBothExist=drBoth.Read(); //关闭DataReader drBoth.Close(); conn.Close(); //判断用户是否注册 if(!isRegUserExist) { Response.Write("<script>alert('此用户尚未注册!')"); return false; } //判断用户名与密码是否一致 else if(!isBothExist) { Response.Write("<script>alert('用户名和密码不一致,不能进入!')"); return false; } else return true; } //IsExistNews函数:判断新闻表中是否仍存有此用户发布过的新闻 public bool IsExistNews() { SqlConnection conn=new SqlConnection(); conn.ConnectionString="server=(local);uid=sa;pwd=;database=jxdb"; conn.Open(); name=TextBoxName.Text.Trim(); //新闻表中是否存在此用户 string sql="select * from news where Name='"+name+"'"; DataSet ds=new DataSet(); SqlDataAdapter da=new SqlDataAdapter(sql,conn); da.Fill(ds,"list"); //取得新闻行数 int count=ds.Tables["list"].Rows.Count; //该用户是否发布过新闻 if(count==0) return false; else return true; conn.Close(); }
(2)、录入页面(Write.aspx):
[ 相关贴图 ]
"注册用户"录入一条新闻所需要的内容,包含标题、关键字、类型、来源部门、发布日期等,同时从登录页面Login.aspx得到用户名,这些信息将被写入数据库中保存。此页面也被用作编辑状态下的"更新"页面,这时,它将根据取得的Title字段值对页面控件初始化。主要事件/函数有:
//InsertDB_news()函数:插入一条新闻 public void InsertDB_news() { //取得类Login中静态变量name的值 string name=Login.name.Trim(); //建立并打开数据库连接 SqlConnection conn=new SqlConnection(); conn.ConnectionString="server=(local);uid=sa;pwd=;database=jxdb"; conn.Open(); //取得编号Id的最大值,然后递增 string sql="select max(Id) as id from news"; //建立数据集 DataSet ds=new DataSet(); SqlDataAdapter da=new SqlDataAdapter(sql,conn); da.Fill(ds,"list"); //声明DataTable DataTable dt; dt=ds.Tables["list"]; DataRow dr=dt.NewRow(); dr=dt.Rows[0]; DataColumn dc; dc=dt.Columns[0]; //最大Id只有一行,取得0行0列的值 string s1=dr[dc].ToString(); //如果此数据库为空 if(s1.Trim()=="") s1="0"; //得到Id+1值 int id=Int32.Parse(s1)+1; //sql语句 sql="insert into news values(@id,@name,@title,@keywords,@type,@fromwhere,@content,@datetime)"; SqlCommand cmd=new SqlCommand(sql,conn); //Id字段 cmd.Parameters.Add(new SqlParameter("@id",SqlDbType.Int,4)); cmd.Parameters["@id"].value =id; //Name字段 cmd.Parameters.Add(new SqlParameter("@name",SqlDbType.Char,10)); cmd.Parameters["@name"].value=Login.name; //Title字段 cmd.Parameters.Add(new SqlParameter("@title",SqlDbType.Char,20)); cmd.Parameters["@title"].value =TextBoxTitle.Text; //Keywords字段 cmd.Parameters.Add(new SqlParameter("@keywords",SqlDbType.Char,20)); cmd.Parameters["@keywords"].value =TextBoxKeywords.Text; //Type字段 cmd.Parameters.Add(new SqlParameter("@type",SqlDbType.Char,10)); cmd.Parameters["@type"].value =DropDownListType.SelectedItem.Text; //Fromwhere字段 cmd.Parameters.Add(new SqlParameter("@fromwhere",SqlDbType.Char,10)); cmd.Parameters["@fromwhere"].value =DropDownListFromwhere.SelectedItem.Text; //Content字段 string txt=TextBoxContent.Text; cmd.Parameters.Add(new SqlParameter("@content",SqlDbType.Char,500)); cmd.Parameters["@content"].value =txt; //Datetime字段 string date; //如果选择了"当前日期"项 if(RadioButtonListDate.SelectedIndex==0) date=DateTime.Now.ToShortDateString(); //否则,使用"日历选择"的日期 else date=TextBoxCalendar.Text; cmd.Parameters.Add(new SqlParameter("@datetime",SqlDbType.Char,20)); cmd.Parameters["@datetime"].value =date; //执行 cmd.ExecuteNonQuery(); conn.Close(); } //IdToPageInit()函数:isFirst、getId值判断如何对页面初始化 //由于此页面对应两种状态:新闻录入和新闻更新状态,前者需要页面保持空白 //后者却需要填充数据库中得到的内容,这一功能通过类Login中静态变量isFirst来实现。 public void IdToPageInit() { //取得类Login中静态变量isFirst值,它用以区别该页面该处于录入状态还是更新状态 //避免从首页"注册用户登录"时,页面控件使用从manage.aspx得到的Id值 if(Login.isFirst!="录入新闻页面") { //如果write.aspx页面是因为在Manage.aspx页面中点击"编辑"按钮 //而调用的,需要用从manage.aspx中得到的Id值作为查询条件 //取得Manage类中静态变量getId的值,得到编号字段Id值 if(Manage.getId!="") { //按钮状态 ButtonUpdate.Enabled =true; ButtonSubmit.Enabled =false; SqlConnection conn=new SqlConnection(); conn.ConnectionString="server=(local);uid=sa;pwd=;database=jxdb"; conn.Open(); //得到Id int id=Int32.Parse(Manage.getId); //sql字符串 string sql="select * from news where Id='"+id+"'"; DataSet ds=new DataSet(); SqlDataAdapter da=new SqlDataAdapter(sql,conn); //建立数据集 da.Fill(ds,"init"); DataTable dt=ds.Tables["init"]; //应该只有一行 DataRow dr=dt.Rows[0]; //标题字段Title string title=dr["Title"].ToString().Trim(); TextBoxTitle.Text=title; //关键字Keywords string keywords=dr["Keywords"].ToString().Trim(); TextBoxKeywords.Text=keywords; //类别Type string type=dr["Type"].ToString().Trim(); DropDownListType.SelectedItem.Text=type; //来源Fromwhere string fromwhere=dr["Fromwhere"].ToString().Trim(); DropDownListFromwhere.SelectedItem.Text=fromwhere; //内容Content string content=dr["Content"].ToString().Trim(); TextBoxContent.Text=content; } } } //"更新"按钮事件 private void ButtonUpdate_Click(object sender, System.EventArgs e) { //应该判断修改后的标题是否已经存在 SqlConnection conn=new SqlConnection(); conn.ConnectionString="server=(local);uid=sa;pwd=;database=jxdb"; conn.Open(); //从manage.aspx页面的静态域中取得关键字段id值 int id=Int32.Parse(Manage.getId); string sql="update news set Id=@id, Name=@name,Title=@title,Keywords=@keywords, Type=@type, Fromwhere=@fromwhere,Content=@content, Datetime=@datetime where Id='"+id+"'"; SqlCommand cmd=new SqlCommand(sql,conn); //id字段 cmd.Parameters.Add(new SqlParameter("@id",SqlDbType.Int,4)); cmd.Parameters["@id"].value =id; //取得姓名值name string name=Login.name.Trim(); cmd.Parameters.Add(new SqlParameter("@name",SqlDbType.Char,10)); cmd.Parameters["@name"].value=name; //标题字段title string title=TextBoxTitle.Text.Trim(); cmd.Parameters.Add(new SqlParameter("@title",SqlDbType.Char,20)); cmd.Parameters["@title"].value =title; //关键字keywords string keywords=TextBoxKeywords.Text.Trim(); cmd.Parameters.Add(new SqlParameter("@keywords",SqlDbType.Char,20)); cmd.Parameters["@keywords"].value =keywords; //类别type string type=DropDownListType.SelectedItem.Text.Trim(); cmd.Parameters.Add(new SqlParameter("@type",SqlDbType.Char,10)); cmd.Parameters["@type"].value =type; //来源部门fromwhere string fromwhere=DropDownListFromwhere.SelectedItem.Text.Trim(); cmd.Parameters.Add(new SqlParameter("@fromwhere",SqlDbType.Char,10)); cmd.Parameters["@fromwhere"].value =fromwhere; //内容content string content=TextBoxContent.Text.Trim(); cmd.Parameters.Add(new SqlParameter("@content",SqlDbType.Char,500)); cmd.Parameters["@content"].value =content; //日期datetime string datetime; //如果选择了"当前日期"项 if(RadioButtonListDate.SelectedIndex==0) datetime=DateTime.Now.ToLongDateString().Trim(); //否则,使用"日历选择"的日期 else datetime=TextBoxCalendar.Text.Trim(); cmd.Parameters.Add(new SqlParameter("@datetime",SqlDbType.Char,20)); cmd.Parameters["@datetime"].value =datetime; cmd.ExecuteNonQuery(); conn.Close(); //提示信息 string message="OK,更新成功!\\n"; message+="你可以继续发布或更新\\n"; message+="也可以返回调用处!!"; Response.Write("<script>alert('"+message+"')"); }
3)、管理中心页面(Manage.aspx):
分页罗列登录用户曾发布过且未删除的新闻信息,用户可以对该条新闻进行删除、修改。非新闻发布者不具有对该条新闻的处理权限,所以不同用户进入此页面将显示不同的内容。
[ 相关贴图 ]
主要事件/函数有:
//编辑事件 private void DataGridManage_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e) { //取得类Login中静态变量isFirst值,以此对Write.aspx初始化 Login.isFirst="更新新闻页面"; //从被点击项的标志号得到关键字段Id的值 getId=DataGridManage.DataKeys[e.Item.ItemIndex].ToString(); //绑定数据源 GridDataBind();//数据绑定与显示 //跳转到write.aspx,期望以Id值对页面进行初始化 Response.Redirect("Write.aspx"); } //删除记录事件 private void DataGridManage_DeleteCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e) { SqlConnection conn=new SqlConnection(); conn.ConnectionString="server=(local);uid=sa;pwd=;database=jxdb"; conn.Open(); string sql="delete from news where Id=@id"; SqlCommand cmd=new SqlCommand(sql,conn); //得到被点击项的关键字段id int id=Int32.Parse(DataGridManage.DataKeys[(int)e.Item.ItemIndex].ToString()); cmd.Parameters.Add(new SqlParameter("@id",SqlDbType.Int,4)); cmd.Parameters["@id"].value=id; cmd.ExecuteNonQuery(); conn.Close(); GridDataBind();//数据绑定与显示 Response.Write("<script>alert('删除成功!')");
为避免用户误删除,客户端使用了一段javascript脚本,以即时信息提示用户的操作。
<script language="javascript"> function delete_confirm(e) { if(event.srcElement.outerText=="删除") event.returnvalue=confirm("真的要删除吗?"); } document.onclick=delete_confirm;
(4)、浏览页面(View.aspx):
分页罗列出网站所有新闻的信息,包括标题Title字段、类型Type字段、来源部门Fromwhere字段及发布日期Datetime字段,每条新闻的标题被做成了一个超链接,点击它们将跳转到新闻阅读页面(Read.aspx);此页面还提供了新闻查询功能,输入待查找的内容及选定分类信息可以快速地找到符合条件的新闻,并使用此页面输出查询结果。
[ 相关贴图 ]
主要事件/函数有:
//Query()函数:实现查询功能 public void Query() { //建立并打开数据库连接 SqlConnection conn=new SqlConnection(); conn.ConnectionString="server=(local);uid=sa;pwd=;database=jxdb"; conn.Open(); //得到待查找内容 string txt=TextBoxQuery.Text.Trim(); //搜索条件分类 string sql; //初始化时sql串 if(txt=="") sql="select * from news"; //否则是因为点击按钮"查找" else { //得到搜索分类字符串 string sort=DropDownListQuery.SelectedItem.Text.Trim(); switch(sort) { case "标 题": sort="Title"; break; case "来源部门": { txt=DropDownListFromwhere.SelectedItem.Text.Trim(); //将选择填入待查内容文本框 TextBoxQuery.Text=txt.Trim(); sort="Fromwhere"; break; } case "关键字": sort="Keywords"; break; case "类 型": { txt=DropDownListType.SelectedItem.Text.Trim(); //将选择填入待查内容文本框 TextBoxQuery.Text=txt; sort="Type"; break; } default: sort="Title"; break; } //组合sql字符串 sql="select * from news where "+sort+" like "+"'%"+txt+"%'"; } DataSet ds=new DataSet(); SqlDataAdapter da=new SqlDataAdapter(sql,conn); da.Fill(ds,"title"); DataViewTitle=ds.Tables["title"].DefaultView; //得到符合条件的新闻条数 int count=ds.Tables["title"].Rows.Count; string message="符合条件的新闻共"+count+"条!"; LabelQuery.Text=message; //索引条件:按编号从高到底排列:后录入的新闻显示在前 DataViewTitle.Sort="Id desc"; DataGridTitle.DataSource=DataViewTitle; //数据绑定 DataGridTitle.DataBind(); //关闭连接 conn.Close(); }
(5)、阅读页面(Read.aspx):
在其他页面中点击标题链接既进入该页面,此时,每条新闻的详细信息将被取出,包括内容(Content)、标题(Title)、关键字(Keywords)等,并按照相对固定的格式放置在页面的不同区域,所有新闻使用大致相同的页面布局,只是各字段对应的内容不同而已,另外,页面其它位置,可以动态放置其他元件,如网站标志logo、页面广告banner等链接图片,这样可以很容易地实现图文并茂的阅读效果。
[ 相关贴图 ]
主要事件函数有:
//GetData()函数:读新闻,显示新闻中的相关字段值 public void GetData() { //获得标题串title string title=Request["title"].Trim(); //建立并打开数据库连接 SqlConnection conn=new SqlConnection(); conn.ConnectionString="server=(local);uid=sa;pwd=;database=jxdb"; conn.Open(); //得到sql字符串 string sql="select * from news where title='"+title+"'"; DataSet ds=new DataSet(); SqlDataAdapter da=new SqlDataAdapter(sql,conn); da.Fill(ds,"info"); DataTable dt=new DataTable(); dt=ds.Tables["info"]; DataRow dr=dt.Rows[0]; //内容content DataColumn dcContent=dt.Columns[6]; string content=dr[dcContent].ToString().Trim(); content=content.Replace("\r\n"," "); content=content.Replace(" "," "); LabelContent.Text=content; //标题title title=title.Replace("\r\n"," "); title=title.Replace(" "," "); LabelTitle.Text=title; //发布日期datetime DataColumn dcDate=dt.Columns[7]; string date=dr[dcDate].ToString(); LabelDate.Text=date; //关键字keywords DataColumn dcKeywords=dt.Columns[3]; string keywords=dr[dcKeywords].ToString(); keywords=keywords.Replace("\r\n"," "); keywords=keywords.Replace(" "," "); LabelKeywords.Text=keywords.Trim(); //类别type DataColumn dcType=dt.Columns[4]; string type=dr[dcType].ToString(); LabelType.Text=type; //来自fromwhere DataColumn dcFrom=dt.Columns[5]; string fromwhere=dr[dcFrom].ToString(); LabelFromwhere.Text=fromwhere; //关闭连接 conn.Close(); }
附 注:
1、由于各自网站各异,本文没有提供主页上的显示效果,实现时一样是对数据库操作,读者应不难实现。
2、由于篇幅所限,本文没有提供出错检测机制,读者可自行添加。
3、代码下载
程序在:Visual Studio.Net正式版、Sql Server 2000开发版上编制完成
该系统在局域网上稳定运行
|