smhy8187

 

用Asp.net实现基于XML的留言簿--good

一.概要:

  留言簿是网站的一个重要组成部分,是访问者发表意见的场所,也是网站管理员了解网站基本情况的有力工具。所以留言簿在现在的网站中扮演了重要的角色。

  可是在以前开发一个留言簿并不是一件容易的事,开发者的工作量往往会很多。而现在随着微软推出VS.net,相应的技术推陈出新。特别是XML在.net Framework中的广泛运用,使得整个.net构架具有十分优越的基础。在VS.net推出的同时,也伴随而来了一门新兴的语言C#。C#作为微软.net战略的重要部分,具有特别优秀的性能。所以本文的asp.net程序是用C#语言描述的,同时整个程序又是基于XML的。我用到了XML作为程序的数据库,主要是因为所以的服务器都是支持XML文件的。

二.要求:

(1) .Net SDK Beta2及以后版本

(2) 支持Asp.net的Web服务器

三.说明:

本文的实例由两部分组成:

(1) guestpost.aspx-将用户信息添加到一个XML文件中

(2) viewguestbook.aspx-先建立一个数据集对象,建立后,就很容易显示其中的数据了。我这里用到了一个“Repeater”来显示数据集中的数据。还有,读者可试着根据自己的喜好来修改查看页。

四.代码:

(1) guestpost.aspx:

< %@ Page Language="C#" EnableSessionState="False" % >
< %@ Import Namespace="System" % >
< %@ Import Namespace="System.IO" % >
< %@ Import Namespace="System.Data" % >
< %-- 这些是本程序正常运用所必须的名字空间 --% >

< html >
< head >
< title >欢迎来到我的留言簿< /title >
< script Language="C#" runat="server" >
///< summary >
/// 当提交(submit)按钮按下后,调要这个函数
///< /summary >
public void Submit_Click(Object sender, EventArgs e)
{
//保存数据的XML文件的路径
//如果你的路径和下面的不同,则请修改之
string dataFile = "db/guest.xml" ;

//运用一个Try-Catch块完成信息添加功能
try{
//仅当页面是有效的时候才处理它
if(Page.IsValid){

errmess.Text="" ;
//以读的模式打开一个FileStream来访问数据库
FileStream fin;
fin= new FileStream(Server.MapPath(dataFile),FileMode.Open,
FileAccess.Read,FileShare.ReadWrite);
//建立一个数据库对象
DataSet guestData = new DataSet();
//仅从数据库读取XML Schema
guestData.ReadXmlSchema(fin);
fin.Close();
//从数据集的Schema新建一个数据行
DataRow newRow = guestData.Tables[0].NewRow();
//用相应值填写数据行
newRow["Name"]=Name.Text;
newRow["Country"]=Country.Text;
newRow["Email"]=Email.Text;
newRow["Comments"]=Comments.Text;
newRow["DateTime"]=DateTime.Now.ToString();
//填写完毕,将数据行添加到数据集
guestData.Tables[0].Rows.Add(newRow);
//为数据库文件新建另一个写模式的FileStream,并保存文件
FileStream fout ;
fout = new FileStream(Server.MapPath(dataFile),FileMode.Open,
FileAccess.Write,FileShare.ReadWrite);
guestData.WriteXml(fout, XmlWriteMode.WriteSchema);
fout.Close();
//隐藏当前的面板
formPanel.Visible=false;
//显示带有感谢信息的面板
thankPanel.Visible=true;
}
}
catch (Exception edd)
{
//捕捉异常
errmess.Text="写入XML文件出错,原因:"+edd.ToString() ;
}
}
< /script >
< LINK href="mystyle.css" type=text/css rel=stylesheet >
< /head >

(2) viewguestbook.aspx:

< %@ Page Language="C#" % >
< %@ Import Namespace="System" % >
< %@ Import Namespace="System.IO" % >
< %@ Import Namespace="System.Data" % >
< %-- 以上是所需的名字空间 --% >

< html >
< head >
< title >欢迎来到我的留言簿< /title >
< script language="C#" runat=server >
//页面下载完毕后,运行这个脚本
public void Page_Load(Object sender, EventArgs e)
{
//包含所有数据的XML文件的路径
//如果你的路径和下面的不同,则请修改
string datafile = "db/guest.xml" ;

//运用一个Try-Catch块完成信息读取功能
try
{
//建立一个数据集对象
DataSet guestData = new DataSet();
//为数据库文件打开一个FileStream
FileStream fin ;
fin = new FileStream(Server.MapPath(datafile),FileMode.Open,
FileAccess.Read,FileShare.ReadWrite) ;
//把数据库中内容读到数据集中
guestData.ReadXml(fin);
fin.Close();
//将第一个表中的数据集付给Repeater
MyDataList.DataSource = guestData.Tables[0].DefaultView;
MyDataList.DataBind();
}
catch (Exception edd)
{
//捕捉异常
errmess.Text="不能从XML文件读入数据,原因:"+edd.ToString() ;
}
}
< /script >
< LINK href="mystyle.css" type=text/css rel=stylesheet >
< /head >

五.总结:

  这个程序完成了,相信大家对实现原理以及技巧都有了大致的了解。通过本文,我主要是想向大家展示用XML处理一些数据库问题时的优点:服务器都支持XML文件,而且处理过程相当简洁明了。当然,用XML也有它的不足之处,就是当数据库很大时,解析过程会花费相当长的时间,因此还是要采用大型的数据库系统的。所以,我只想通过此文起到抛砖引玉的作用。 


---------------------------------------

using System;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Xml;
using System.IO;

/// <summary>
/// 论坛类别的操作类
/// </summary>
public class BBSManager
{
    //定义常量表示字段名称或SQL语句。
    private const string SQL_INSERT_BBSINFO = "INSERT INTO bbsinfo VALUES "+
        "(@title,@filename,@posttime,@replycount,@lastreplytime, @postuser,@categoryid)";
    private const string PARM_BBS_TITLE = "@title";
    private const string PARM_BBS_FILENAME = "@filename";
    private const string PARM_BBS_POSTTIME = "@posttime";
    private const string PARM_BBS_REPLYCOUNT = "@replycount";
    private const string PARM_BBS_LASTREPLYTIME = "@lastreplytime";
    private const string PARM_BBS_POSTUSER = "@postuser";
    private const string PARM_BBS_CATEGORYID = "@categoryid";
    private string xmlfilename = "";
 public BBSManager()
 {
 }
    /// <summary>
    /// 添加论坛的类别
    /// </summary>
    /// <param name="name">类别名称</param>
    /// <param name="des">类别描述信息</param>
    /// <returns>添加是否成功</returns>
    public bool AddBBSCategory(string name,string des )
    {
        //使用StringBuild连接字符串比使用“+”效率高很多
        StringBuilder strSQL = new StringBuilder();
        //创建论坛添加方法的参数
        SqlParameter[] newsParms = new SqlParameter[]{
            new SqlParameter("@name", SqlDbType.NVarChar,20),
            new SqlParameter("@des", SqlDbType.NVarChar,100)};

        //创建执行语句的SQL命令
        SqlCommand cmd = new SqlCommand();
        // 依次给参数赋值
        newsParms[0].Value = name;
        newsParms[1].Value = des;

        //遍历所有参数,并将参数添加到SqlCommand命令中
        foreach (SqlParameter parm in newsParms)
            cmd.Parameters.Add(parm);
        //获取数据库的连接字符串
        using (SqlConnection conn = new SqlConnection(SqlHelper.ConnectionStringLocalTransaction))
        {
            //加载“添加类别”执行语句
            strSQL.Append("Insert into BBSCategory values(@name,@des)");
            //打开数据库连接,执行命令
            conn.Open();
            //设置Sqlcommand命令的属性
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = strSQL.ToString();
            //执行添加的SqlCommand命令
            int val = cmd.ExecuteNonQuery();
            //清空SqlCommand命令中的参数
            cmd.Parameters.Clear();
            //判断是否添加成功,注意返回的是添加是否成功,不是影响的行数
            if (val > 0)
                return true;
            else
                return false;
        }
    }
    /// <summary>
    /// 将发帖内容保存到XML文件中的方法
    /// </summary>
    /// <param name="filename">XML文件路径全名</param>
    /// <param name="title">XML文件路径全名</param>
    /// <param name="content">XML文件路径全名</param>
    /// <param name="user">XML文件路径全名</param>
    public void AddXML(string filename,string title,string content,string user)
    {
        //初始化XML文档操作类
        XmlDocument mydoc = new XmlDocument();
        //加载指定的XML文件
        mydoc.Load(filename);

        //添加元素-帖子主题
        XmlElement ele = mydoc.CreateElement("title");
        XmlText text = mydoc.CreateTextNode(title);
        //添加元素-发帖时间
        XmlElement ele1 = mydoc.CreateElement("posttime");
        XmlText text1 = mydoc.CreateTextNode(DateTime.Now.ToString());
        //添加元素-内容
        XmlElement ele2 = mydoc.CreateElement("content");
        XmlText text2 = mydoc.CreateTextNode(content);
        //添加元素-发帖人
        XmlElement ele3 = mydoc.CreateElement("postuser");
        XmlText text3 = mydoc.CreateTextNode(user);

        //添加文件的节点-msgrecord
        XmlNode newElem = mydoc.CreateNode("element", "xmlrecord", "");
        //在节点中添加元素
        newElem.AppendChild(ele);
        newElem.LastChild.AppendChild(text);
        newElem.AppendChild(ele1);
        newElem.LastChild.AppendChild(text1);
        newElem.AppendChild(ele2);
        newElem.LastChild.AppendChild(text2);
        newElem.AppendChild(ele3);
        newElem.LastChild.AppendChild(text3);
        //将节点添加到文档中
        XmlElement root = mydoc.DocumentElement;
        root.AppendChild(newElem);

        //获取文件路径
        int index = filename.LastIndexOf(@"\");
        string path = filename.Substring(0, index);
        //新文件名
        path = path + @"\" + xmlfilename + "file.xml";
        //文件创建后必须关闭,否则其他程序无法调用
        FileStream mystream =File.Create(path);
        mystream.Close();

        //保存所有修改-到指定文件中:注意编码语言的选择
        XmlTextWriter mytw = new XmlTextWriter(path,Encoding.Default);
        mydoc.Save(mytw);
        mytw.Close();
    }
    /// <summary>
    ///
    /// </summary>
    /// <param name="title"></param>
    /// <param name="filename"></param>
    /// <param name="replycount"></param>
    /// <param name="categoryid"></param>
    public void AddMsg(string title,string user,int categoryid)
    {
        //使用StringBuild连接字符串比使用“+”效率高很多
        StringBuilder strSQL = new StringBuilder();
        //获取缓存参数,如果没有,此方法会自动创建缓存列表
        SqlParameter[] newsParms = GetParameters();
        //创建执行语句的SQL命令
        SqlCommand cmd = new SqlCommand();
        // 依次给参数赋值
        newsParms[0].Value = title;
        //一个获取文件名的私有方法
        newsParms[1].Value = getFilename().ToString();
        xmlfilename = getFilename().ToString();
        //注意发布的日期取当日
        newsParms[2].Value = DateTime.Now;
        //默认添加的回复数是0
        newsParms[3].Value = 0;
        newsParms[4].Value = DateTime.Now;
        newsParms[5].Value = user;
        newsParms[6].Value = categoryid;

        //遍历所有参数,并将参数添加到SqlCommand命令中
        foreach (SqlParameter parm in newsParms)
            cmd.Parameters.Add(parm);
        //获取数据库的连接字符串
        using (SqlConnection conn = new SqlConnection(SqlHelper.ConnectionStringLocalTransaction))
        {
            strSQL.Append(SQL_INSERT_BBSINFO);
            //打开数据库连接,执行命令
            conn.Open();
            //设置Sqlcommand命令的属性
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = strSQL.ToString();
            //执行添加的SqlCommand命令
            int val = cmd.ExecuteNonQuery();
            //清空SqlCommand命令中的参数
            cmd.Parameters.Clear();
        }
    }
    /// <summary>
    /// 创建或获取缓存参数的私有方法
    /// </summary>
    /// <returns>返回参数列表</returns>
    private static SqlParameter[] GetParameters()
    {
        //将SQL_INSERT_NEWSINFO做为哈希表缓存的键值
        SqlParameter[] parms = SqlHelper.GetCachedParameters(SQL_INSERT_BBSINFO);

        //首先判断缓存是否已经存在
        if (parms == null)
        {
            //缓存不存在的情况下,新建参数列表
            parms = new SqlParameter[] {
                    new SqlParameter(PARM_BBS_TITLE, SqlDbType.NVarChar,50),
                    new SqlParameter(PARM_BBS_FILENAME, SqlDbType.NVarChar,100),
                    new SqlParameter(PARM_BBS_POSTTIME, SqlDbType.DateTime),
                    new SqlParameter(PARM_BBS_REPLYCOUNT, SqlDbType.Int),
                    new SqlParameter(PARM_BBS_LASTREPLYTIME, SqlDbType.DateTime),
                    new SqlParameter(PARM_BBS_POSTUSER, SqlDbType.NVarChar, 50),
                    new SqlParameter(PARM_BBS_CATEGORYID, SqlDbType.Int) };

            //将新建的参数列表添加到哈希表中缓存起来
            SqlHelper.CacheParameters(SQL_INSERT_BBSINFO, parms);
        }
        //返回参数数组
        return parms;
    }
    /// <summary>
    /// 更新数据库中的回复时间
    /// </summary>
    /// <param name="infoid">帖子的ID</param>
    /// <returns>是否更新成功</returns>
    public bool UpdateMsg(int infoid)
    {
        //使用StringBuild连接字符串比使用“+”效率高很多
        StringBuilder strSQL = new StringBuilder();
        //创建论坛添加方法的参数
        SqlParameter[] newsParms = new SqlParameter[]{
            new SqlParameter("@lastposttime", SqlDbType.DateTime),
            new SqlParameter("@infoid", SqlDbType.Int)};

        //创建执行语句的SQL命令
        SqlCommand cmd = new SqlCommand();
        // 依次给参数赋值
        newsParms[0].Value = DateTime.Now;
        newsParms[1].Value = infoid;

        //遍历所有参数,并将参数添加到SqlCommand命令中
        foreach (SqlParameter parm in newsParms)
            cmd.Parameters.Add(parm);
        //获取数据库的连接字符串
        using (SqlConnection conn = new SqlConnection(SqlHelper.ConnectionStringLocalTransaction))
        {
            //加载“添加类别”执行语句
            strSQL.Append("UPDATE bbsinfo  SET replycount=replycount+1 ,  lastreplytime=@lastposttime  WHERE infoid=@infoid");
            //打开数据库连接,执行命令
            conn.Open();
            //设置Sqlcommand命令的属性
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = strSQL.ToString();
            //执行添加的SqlCommand命令
            int val = cmd.ExecuteNonQuery();
            //清空SqlCommand命令中的参数
            cmd.Parameters.Clear();
            //判断是否添加成功,注意返回的是添加是否成功,不是影响的行数
            if (val > 0)
                return true;
            else
                return false;
        }
    }
    /// <summary>
    /// 给新建的xml文件起名
    /// </summary>
    /// <returns>返回的是最大号的ID+1</returns>
    private int getFilename()
    {
        int cardrule = 0;
        //设置SQL语句,取最大的ID值
        string strsql = "select top 1 infoid from bbsinfo order by infoid desc ";
        //调用SqlHelper访问组件的方法返回第一行第一列的值
        try
        {
            cardrule = (int)SqlHelper.ExecuteScalar(SqlHelper.ConnectionStringLocalTransaction, CommandType.Text, strsql, null);
            //返回最大值+1
        }
        catch
        {
            //此时数据库中无数据
            cardrule = 0;
        }
        return cardrule +1;

    }
    /// <summary>
    /// 更新回复内容
    /// </summary>
    /// <param name="filename">文件名</param>
    /// <param name="title">回复主题</param>
    /// <param name="content">回复内容</param>
    /// <param name="user">回复人</param>
    public void UpdateXml(string filename,string title,string content,string user)
    {
        //初始化XML文档操作类
        XmlDocument mydoc = new XmlDocument();
        //加载指定的XML文件
        mydoc.Load(filename);

        //添加元素-帖子主题
        XmlElement ele = mydoc.CreateElement("title");
        XmlText text = mydoc.CreateTextNode(title);
        //添加元素-发帖时间
        XmlElement ele1 = mydoc.CreateElement("posttime");
        XmlText text1 = mydoc.CreateTextNode(DateTime.Now.ToString());
        //添加元素-内容
        XmlElement ele2 = mydoc.CreateElement("content");
        XmlText text2 = mydoc.CreateTextNode(content);
        //添加元素-发帖人
        XmlElement ele3 = mydoc.CreateElement("postuser");
        XmlText text3 = mydoc.CreateTextNode(user);

        //添加文件的节点-msgrecord
        XmlNode newElem = mydoc.CreateNode("element", "xmlrecord", "");
        //在节点中添加元素
        newElem.AppendChild(ele);
        newElem.LastChild.AppendChild(text);
        newElem.AppendChild(ele1);
        newElem.LastChild.AppendChild(text1);
        newElem.AppendChild(ele2);
        newElem.LastChild.AppendChild(text2);
        newElem.AppendChild(ele3);
        newElem.LastChild.AppendChild(text3);
        //将节点添加到文档中
        XmlElement root = mydoc.DocumentElement;
        root.AppendChild(newElem);
        //保存所有的修改
        mydoc.Save(filename);
    }
}


posted on 2007-07-02 17:22  new2008  阅读(212)  评论(0编辑  收藏  举报

导航