C#写的完全用类封装的UBB留言板(程序部分)

bbs.cs

using System;
using System.Data;
using System.Data.ADO;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Text.RegularExpressions ;
using System.Collections ;

public class BBS:Page
{
    private String m_strCnn;
    private int m_nPageSize;
    private int m_nPageCount;
    private int m_nRecordCount;
    private int m_nAbsolutePage;
    
    protected Table tblBBS;
    
    protected LinkButton lbPrevPage;
    protected LinkButton lbNextPage;
    protected LinkButton lbLastPage;
    protected LinkButton lbFirstPage;
    protected LinkButton lbFreshPage;
    protected LinkButton lbAdmin;

    protected Button btnAdd;

    protected TextBox txtAuthor;
    protected TextBox txtHomePage;
    protected TextBox txtEmail;
    protected TextBox txtBody;
    protected TextBox txtOP;
    protected TextBox txtID;
    protected TextBox txtAnswer;
    protected TextBox txtPage;

    protected Panel pnlAdmin;
    protected Panel pnlAnswer;
    protected TextBox txtAdminUID;
    protected TextBox txtAdminPWD;
    CustomValidator cusAdminUID;

    const String ADMIN_UID="chinaspx";
    const String ADMIN_PWD="gnome";

    public String ConnectionString
    {
        get
        {
            return m_strCnn;
        }
        set
        {
            m_strCnn=value;
        }
    }
    
    public int AbsolutePage
    {
        get
        {
            return m_nAbsolutePage;
        }
    }

    public int RecordCount
    {
        get
        {
            return m_nRecordCount;
        }
    }

    public int PageCount
    {
        get
        {
            return m_nPageCount;
        }
    }

    public int PageSize
    {
        get
        {
            return m_nPageSize;
        }
    }

    public BBS()
    {
        m_strCnn="DBQ="+Server.MapPath("./db/gb.mdb")+";DRIVER={Microsoft Access Driver (*.mdb)};";
        m_nPageSize=10;
        m_nPageCount=0;
        m_nRecordCount=0;
        m_nAbsolutePage=1;
    
        String strSQL="SELECT Count(*) as Num FROM GB";
        ADOCommand cmm=new ADOCommand(strSQL,m_strCnn);
        ADODataReader adr;
        float fPage;

        try
        {
            cmm.ActiveConnection.Open();
            cmm.Execute(out adr);
            
            if(adr.Read())
                m_nRecordCount=Int32.Parse(adr["Num"].ToString());
            
            adr.Close();

            fPage=m_nRecordCount/m_nPageSize;

            if((fPage*m_nPageSize)<(float)m_nRecordCount)
                m_nPageCount=(int)fPage+1;
            else
                m_nPageCount=(int)fPage;
            
        }
        catch(Exception exp)
        {
            throw new Exception("Error:Init BBS "+exp.ToString());
        }
        finally
        {
            cmm.ActiveConnection.Close();
        }
    }

    protected void Page_Load(Object sender,EventArgs e)
    {
        String strOP=null;
        String strID=null;
        
        strOP=Request.QueryString["op"];
        strID=Request.QueryString["id"];

        if(strOP==null)
            strOP=txtOP.Text;
    
        if(strOP.Equals("del")&&strID!=null)
            DelMsg(strID);
        
        if(strOP.Equals("edit")&&strID!=null)
        {    
            pnlAnswer.Visible=true;
            txtID.Text=strID;
        }
        else
            pnlAnswer.Visible=false;
        
            
        pnlAdmin.Visible=false;
        pnlAnswer.Visible=false;

        if(!this.IsPostBack)
            BindData();    
    }
    
    protected void On_Answer(Object sender,EventArgs e)
    {
        if(this.IsValid)    
            Answer();
        BindData();
    }

    private void Answer()
    {
        String strSQL="UPDATE GB SET G_Answer='"+txtAnswer.Text+"' WHERE G_ID="+txtID.Text;
        
        ADOCommand cmm=new ADOCommand(strSQL,m_strCnn);
        
        try
        {
            cmm.ActiveConnection.Open();
            cmm.ExecuteNonQuery();
        }
        catch(Exception exp)
        {
            throw new Exception("Error:Answer "+exp.ToString());
        }
        finally
        {
            cmm.ActiveConnection.Close();
        }

        pnlAnswer.Visible=false;
    }
    
    protected void On_CancelAnswer(Object sender,EventArgs e)
    {
        pnlAnswer.Visible=false;

        BindData();
    }

    private void DelMsg(String strID)
    {
        String strSQL="DELETE FROM GB WHERE G_ID="+strID;
        ADOCommand cmm=new ADOCommand(strSQL,m_strCnn);
        try
        {
            cmm.ActiveConnection.Open();
            cmm.ExecuteNonQuery();
        }
        catch(Exception exp)
        {
            throw new Exception("Error:Deleting message "+exp.ToString());
        }
        finally
        {
            cmm.ActiveConnection.Close();
        }
    }

    private void BindData()
    {
        String strSQL;
        String strCell;
        ADODataSetCommand dsCmd;
        DataSet ds;
        DataTable dt;
        TableRow r;
        TableCell c;
        int nLastPageRecordCount;
        int nCurPageSize;
        int nAbsolutePos;
    
        strSQL="SELECT * FROM GB ORDER BY G_ID DESC";
        dsCmd=new ADODataSetCommand(strSQL,m_strCnn);
        ds=new DataSet();
        
        try
        {
            dsCmd.FillDataSet(ds,"GB");
            dt=ds.Tables["GB"];
            nLastPageRecordCount=m_nRecordCount-(m_nPageCount-1)*m_nPageSize;
            nCurPageSize=m_nAbsolutePage<m_nPageCount?m_nPageSize:nLastPageRecordCount;
            nAbsolutePos=(m_nAbsolutePage-1)*(m_nPageSize-1);
        
            for(int i=nAbsolutePos;i<nAbsolutePos+nCurPageSize;i++)
            {
                r=new TableRow();
                c=new TableCell();
                strCell="名字:"+dt.Rows[i]["G_Author"].ToString();
                strCell+="<br>";
                strCell+="主页地址:"+dt.Rows[i]["G_HomePage"].ToString();
                strCell+="<br>";
                strCell+="留言内容:"+UBB.UnEncode(dt.Rows[i]["G_Body"].ToString());
                strCell+="<font color=#bbbbbb>(发表于:"+dt.Rows[i]["G_PubDT"].ToString()+"</font>";
                strCell+="<br>";
                strCell+="<b>斑主回复:</b>"+dt.Rows[i]["G_Answer"].ToString();
                
                if(Session["IsAdmin"]!=null)
                {
                    strCell+="<br>";
                    strCell+="<a href='"+Request.ServerVariables["SCRIPT_NAME"]+"?op=edit&id="+dt.Rows[i]["G_ID"].ToString()+"'><img src='images/msg.gif' border='0' align='absmiddle'>回复</a>";
                    strCell+="<a href='"+Request.ServerVariables["SCRIPT_NAME"]+"?op=del&id="+dt.Rows[i]["G_ID"].ToString()+"'><img src='images/recycle.gif' border='0' align=' absmiddle'>删除</a>";
                    strCell+="<br>";
                }

                strCell+="<hr size='1' noshadow>";
                c.Controls.Add(new LiteralControl(strCell));
                c.CssClass="content";
                r.Cells.Add(c);
                tblBBS.Rows.Add(r);
            }
        }
        catch(Exception exp)
        {
            throw new Exception("While page loading...Error:"+exp.ToString());
        }
    }
    
    protected void On_NextPage(Object sender,EventArgs e)
    {
        int nTmpPage=Int32.Parse(txtPage.Text)+1;        
        m_nAbsolutePage=(nTmpPage>=m_nPageCount)?m_nPageCount:nTmpPage;
        txtPage.Text=Int32.ToString(m_nAbsolutePage);
        PageState();
        BindData();    
    }

    protected void On_PrevPage(Object sender,EventArgs e)
    {
        int nTmpPage=Int32.Parse(txtPage.Text)-1;
        m_nAbsolutePage=(nTmpPage<=1)?1:nTmpPage;
        txtPage.Text=Int32.ToString(m_nAbsolutePage);
        PageState();
        BindData();        
    }

    protected void On_FreshPage(Object sender,EventArgs e)
    {
        PageState();
        BindData();
    }

    protected void On_FirstPage(Object sender,EventArgs e)
    {
        m_nAbsolutePage=1;
        txtPage.Text="1";
        PageState();
        BindData();
    }

    protected void On_LastPage(Object sender,EventArgs e)
    {
        m_nAbsolutePage=m_nPageCount;
        txtPage.Text=Int32.ToString(m_nPageCount);
        PageState();
        BindData();
    }

    protected void On_Add(Object sender,EventArgs e)
    {
        if(this.IsValid)
        {    
            InsertData();
            ClearTextBox();
        }
        BindData();
    }
    
    protected void On_Admin(Object sender,EventArgs e)
    {
        pnlAdmin.Visible=true;
        pnlAnswer.Visible=false;
        BindData();
    }

    protected void On_Logout(Object sender,EventArgs e)
    {
        pnlAdmin.Visible=false;
        pnlAnswer.Visible=false;
        Session["IsAdmin"]=null;
        BindData();
    }
    
    protected void On_Login(Object sender,EventArgs e)
    {
        if(txtAdminUID.Text.Equals(ADMIN_UID)&&txtAdminPWD.Text.Equals(ADMIN_PWD))
        {
            Session["IsAdmin"]=true;
            pnlAdmin.Visible=false;
        }
        else
            pnlAdmin.Visible=true;
        BindData();
    }

    protected void On_CanelLogin(Object sender,EventArgs e)
    {
        pnlAdmin.Visible=false;
        pnlAnswer.Visible=false;
        BindData();
    }

    private void ClearTextBox()
    {
        txtBody.Text="";
    }
    
    private void PageState()
    {
        if(m_nAbsolutePage==1)
        {
            lbFirstPage.Enabled=false;
            lbPrevPage.Enabled=false;
        }
        else
        {
            lbFirstPage.Enabled=true;
            lbPrevPage.Enabled=true;
        }

        if(m_nAbsolutePage==m_nPageCount)
        {
            lbLastPage.Enabled=false;
            lbNextPage.Enabled=false;
        }
        else
        {
            lbLastPage.Enabled=true;
            lbNextPage.Enabled=true;
        }
    }

    private void InsertData()
    {
        String strSQL="INSERT INTO GB(G_Author,G_Email,G_Body,G_HomePage,G_PubDT) VALUES(?,?,?,?,?)";
        ADOCommand cmm=new ADOCommand(strSQL,m_strCnn);
        
        cmm.Parameters.Add(new ADOParameter("@Author",ADODBType.VarWChar,50));
        cmm.Parameters["@Author"].Value=txtAuthor.Text;
        
        cmm.Parameters.Add(new ADOParameter("@Email",ADODBType.VarWChar,50));
        cmm.Parameters["@Email"].Value=txtEmail.Text;
        
        cmm.Parameters.Add(new ADOParameter("@Body",ADODBType.LongVarWChar));
        cmm.Parameters["@Body"].Value=txtBody.Text;

        cmm.Parameters.Add(new ADOParameter("@HomePage",ADODBType.VarWChar,50));
        cmm.Parameters["@HomePage"].Value=txtHomePage.Text;

        cmm.Parameters.Add(new ADOParameter("@PubDT",ADODBType.DBDate));
        cmm.Parameters["@PubDT"].Value=DateTime.Today;

        try
        {
            cmm.ActiveConnection.Open();
            cmm.ExecuteNonQuery();
        }
        catch(Exception exp)
        {
            throw new Exception("Error:Insert Data "+exp.ToString());
        }
        finally
        {
            cmm.ActiveConnection.Close();
        }
    }
}

public class UBB
{
    public UBB()
    {
    }

    public static String UnEncode(String str)
    {
        //首先替换< , >
        str = Regex.Replace(str , "<" , "&lt;") ;
        str = Regex.Replace(str , ">" , "&gt;") ;

        //-----------处理可以直接替换的,开始--------------------------------------
        ArrayList arrTag = new ArrayList() ;

        /**********这段正则表达式的模板定义傻得很,如果有相关资料需要改正*************/
        //粗体  
        arrTag.Add (new Tag("[[]b[]]" , "<b>" , "[[]/b[]]" , "</b>")) ;     
       
        //下划线
        arrTag.Add (new Tag("[[]u[]]" , "<u>" , "[[]/u[]]" , "</u>")) ;     
       
        //斜体
        arrTag.Add (new Tag("[[]i[]]" , "<i>" , "[[]/i[]]" , "</i>")) ;
       
        //Table
        arrTag.Add (new Tag( "[[]table[]]" , "<table>" ,"[[]/table[]]" , "</table>")) ;
            //Tr
        arrTag.Add (new Tag( "[[]tr[]]" , "<tr>" , "[[]/tr[]]" , "</tr>")) ;
            //Td
        arrTag.Add (new Tag( "[[]td[]]" , "<td>" , "[[]/td[]]" , "</td>")) ;
                       
            //pre
        arrTag.Add (new Tag( "[[]code[]]" , "<pre>" , "[[]/code[]]" , "</pre>")) ;
        
            //quote
        arrTag.Add (new Tag( "[[]quote[]]" , "<quote>" , "[[]/quote[]]" , "</quote>")) ;
            //ul
        arrTag.Add (new Tag( "[[]list[]]" , "<ul>" ,"[[]/list[]]" , "</ul>")) ;
       
            //li
        arrTag.Add (new Tag( "[[]li[]]" , "<li>" ,"[[]/li[]]" , "</li>")) ;
       
            //标题
        for (int i = 1 ; i < 7 ; i ++)
        {
            arrTag.Add (new Tag("[[]h" + i.ToString() + "[]]" , "<h" + i.ToString() + ">" ,
                                "[[]/h" + i.ToString() + "[]]" , "</h" + i.ToString() + ">")) ;
        }                   
       
        MatchCollection objMatches ;
            //替换
        for (int i = 0 ; i < arrTag.Count ; i++ )
        {
            Regex objReg = new Regex(((Tag)arrTag[i]).BeginPattern
                                + ".*" + ((Tag)arrTag[i]).EndPattern ,"i") ;
            objMatches = objReg.Matches(str ) ;
             
             
            for (int j = 0 ; j < objMatches.Count ; j++)
            {
                int m = ((Tag)arrTag[i]).BeginPattern.Length - 4 ;
                int n = objMatches[j].ToString().Length - m - ((Tag)arrTag[i]).EndPattern.Length + 4  ;
                String strContent = objMatches[j].ToString().Substring(m , n) ;
                str = Regex.Replace(str , Regex.Escape(objMatches[j].ToString()) ,
                ((Tag)arrTag[i]).BeginTag + strContent + ((Tag)arrTag[i]).EndTag) ;            
            }                                                 
                                                        
        }

        
        //-----------处理颜色,开始------------------------------------------------
        objMatches = Regex.Matches(str ,"[[][#].{6}[]]") ;
        for (int i = 0 ; i < objMatches.Count ; i++ )
        {
            str = Regex.Replace(str , Regex.Escape(objMatches[i].ToString()) ,
                             "<font color=#" + objMatches[i].ToString().Substring(2 , 6) + ">" ) ;
            str = Regex.Replace(str , Regex.Escape("[/#]") , "</font>") ;
        }
            //-----------处理颜色,结束------------------------------------------------


            //-----------处理url , img等,开始-----------------------------------------
       
        arrTag.Clear() ;      //清空数组
           
            //url
        arrTag.Add (new Tag("[[][uU][rR][lL][]]" , "<a href=http://" ,
                              "[[]/[uU][rR][lL][]]" , "</a>")) ;
       
            //Email
        arrTag.Add (new Tag("[[][eE][mM][aA][iI][lL][]]" , "<a href=mailto:" ,
                              "[[]/[eE][mM][aA][iI][lL][]]" , "</a>")) ;
     
            //img
        arrTag.Add (new Tag("[[][iI][mM][gG][]]" , "<img src=http://" ,
                              "[[]/[iI][mM][gG][]]" , "")) ;
                                                           
       
            //处理
        for (int i = 0 ; i < arrTag.Count ; i++ )
        {
            objMatches = Regex.Matches(str , ((Tag)arrTag[i]).BeginPattern + ".*"
                                            + ((Tag)arrTag[i]).EndPattern) ;
            for (int j = 0 ; j < objMatches.Count ; j ++ )
            {
                    //求出匹配字符串及url在匹配字符串中的位置及长度
                String EntireStr = objMatches[j].ToString() ;
               
                    /***************************注意************************************************/
                    /*计算开始位置,由于没有regex的详细资料,所以计算方法是硬凑出来的,以后应当改进*/
                    /*******************************************************************************/
                int StartIndex = (((Tag)arrTag[i]).BeginPattern.Length - 6)/4 + 2 ;
                int Length   = EntireStr.Length - StartIndex
                             - (((Tag)arrTag[i]).EndPattern.Length -1) / 3 ;
                String Url =  EntireStr.Substring(StartIndex , Length)  ;  
                    /******************************************************************************/
               
               
                    //替换              
                str = Regex.Replace(str , Regex.Escape(EntireStr) ,
                                   ((Tag)arrTag[i]).BeginTag
                                 + Regex.Replace(Url , "[hH][tT][tT][pP]://" , "") + ">"
                                 + (((Tag)arrTag[i]).BeginPattern == "[[][iI][mM][gG][]]" ? "" : Url)    
                                 + ((Tag)arrTag[i]).EndTag) ;
            }
        }                                                                             

       
            //-----------处理url , img等,结束-----------------------------------------
       
            //处理带标题的url
       
       
        objMatches = Regex.Matches(str , "[[][uU][rR][lL]=[^]]*[]]") ;
       
        for (int i = 0 ; i < objMatches.Count ; i ++)
        {
                //Trace.Write ("Function UnEncode : ln139" , objMatches[i].ToString() + "<br>") ;
            str = Regex.Replace ( str ,  Regex.Escape(objMatches[i].ToString()) ,
                                 "<a href=http://" + Regex.Replace(
                                   objMatches[i].ToString().Substring(5 ,
                                  objMatches[i].ToString().Length - 6) , "[hH][tT][tT][pP]://" ,
                                  "")  + ">")  ;
            str = Regex.Replace ( str , "[[]/url[]]" , "</a>") ;                        
        }

            //格式
        str = Regex.Replace(str , "\r\n" , "<br>") ;
        str = Regex.Replace(str , " " , "&nbsp;") ;
        str = Regex.Replace(str , "\t" , "&nbsp;&nbsp;&nbsp;&nbsp;") ;
       
            //返回结果
        return str ;  
      
    }
}

    public class Tag
    {
        private String m_strBeginTag ;           //开始标记
        private String m_strBeginPattern ;       //开始标记的匹配模板
        private String m_strEndTag   ;           //结束标记
        private String m_strEndPattern   ;       //开始标记的匹配模板
       
        //构造函数
        public Tag() {}  
        public Tag ( String a_strBeginPattern , String a_strBeginTag ,
                    String a_strEndPattern ,   String a_strEndTag)
        {
            m_strBeginPattern  = a_strBeginPattern ;
            m_strBeginTag      = a_strBeginTag ;
            m_strEndPattern    = a_strEndPattern ;
            m_strEndTag        = a_strEndTag ;
         }  
       
        //属性  
        public String BeginTag
        {
            get
            {
                return m_strBeginTag ;
            }
            set
            {
                m_strBeginTag = value ;
            }
         }          
         
       public String BeginPattern
         {
            get
            {
                return m_strBeginPattern ;
            }
            set
            {
                m_strBeginPattern = value ;
             }
        }          
         
        public String EndPattern
        {
            get
            {
                return m_strEndPattern ;
            }
            set
            {
                m_strEndPattern = value ;
            }
        }
                   
        public String EndTag
        {
           get
           {
                return m_strEndTag ;
            }
            set
            {
                m_strEndTag = value ;
            }
        }
    }