一、具有以下特点:
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开发版上编制完成
该系统在局域网上稳定运行