Asp.net+Xml實現無資料庫論壇一點即通

來源:互聯網
上載者:User

Asp.net+Xml實現無資料庫論壇一點即通

************************************************************
原作:風雲舞
日期:2003-12-6 7:37:09
來源:http://www.lshdic.com/bbs
下載:http://www.lshdic.com/download/netxmlbbs.rar
聲明:作者水平有限,如有疏漏、錯字或不對之處望體諒,轉載請保留星號內資訊
************************************************************

起草語:流行論壇(我們重點討論ASP,ASP。NET論壇)的開發思路

老手可略過此節,就讀下節。

目前,網上論壇各式各樣各種版本不計其數,歸根結底如何神通其核心資料存取倉庫都是“資料庫”,我是指我們常用的ACCESS SQLSERVER等等這種形式的“資料庫”,而後由PHP ASP ASP。NET JSP等等這些後台語言通過中心“ADO,SQL”兩條線,像伐木搭橋似的一小塊一小塊(會員註冊、會員登陸、論壇欄目分類、項目統計、單個欄目、文章瀏覽、後台管理……)積木似的累積成形式各異的論壇系統,而這一塊塊的“積木”,如何異樣然終歸就是對資料庫的存取其成分無非就是構成木料的物質不會變成鐵的,可見,好的論壇程式並不難寫,難得是清晰的思路、優質的“資料庫結構”,既然是這樣,下面我就將本人著手開發ASP。NET+XML無資料庫實現論壇總結的一些經驗思路一一陳述,讀畢若有興趣不妨自己動手一試,嘗試一下用全新的手段開發論壇的樂趣

第一節:廢話不說、解答疑問

1:這篇文章需熟悉哪些知識的人才能讀懂?
至少從事學習一年以上WEB後台網站編程綜合知識的人即可讀懂,熟悉ASP。NET編程及XML文檔結構的程式員更能深入意會
2:Xml能充當“資料庫”嗎?
能,只不過是不同的概念和組織形式
3:用Xml充當資料庫製作論壇的開發難度是否比使用ACCESS、SQLSERVER等為資料庫的開發難度高?
高許多,甚至有些功能本人水平有限無從下手解決(XML充當資料庫相比ACCESS等有一定本質上的局限),但並不代表不可能
4:本文為什麼選擇ASP。NET做為背景程式語言來結合XML建造論壇?
無特殊意義,ASP、PHP、JSP或其他背景程式語言均可,甚至VB、VC、JAVA等能以軟體形式表現論壇
5:兩者相比,Xml充當“資料庫”做的論壇或其他系統有何好處?
如程式及XML結構精妙完善,無論在大小程式系統上均在
-速度(基於檔案,相對憂於ADO存取資料庫)
-資源佔用(無論資料總和多少,基本是處理分布式的小型檔案(通常在1-100K內),無論是在記憶體或CPU的佔用等均憂於資料庫)
-分布式(單一的檔案集合於檔案夾,與將Data Integration為一身的資料庫,各有優勢)
-移植性和通用性(XML本身即是一種通用資料描述語言 (Data Description Language),無論是在不同作業系統或程式語言上均能順利移植和應用)
-修改、尋找、維護、批量處理(如資料量大,則必須藉助程式系統操作,如直接在檔案夾管理檔案非常麻煩,這方面遜於資料庫系統的介面和易用性,除非建立自己的XML資料處理軟體或WEB系統彌補這方面的不足)
-安全性(大智慧是取決於程式、加密方面,小聰明是更改後台檔案、檔案夾的名稱和存放位置,只不過基於XML檔案構建的資料庫結構比較散亂,不如資料表封裝的簡單)

第二節:引路入門、建立基地(XML資料庫結構)

明確做什麼樣的論壇系統,才能理起思路,這裡我們假設開發一簡單論壇,其功能功用均效仿常見論壇,我們只要求一個欄目
XML資料庫的實現{
會員資料儲存(在主目錄建立一檔案,名為user.xml,該user.xml檔案即作為儲存所有會員資料的檔案,本例結構可是如下形式)[
<?xml version="1.0" encoding="gb2312"?>
<alluser>
  <fyw name="風雲舞" pass="1234" sex="男士" age="20" img="http://www.lshdic.com/bbs/image/user40.jpg" fatie="20" exp="243" homepage="http://www.lshdic.com" email="lshdic@sina.com" oicq="21152530" qianming="簽名檔內容" address="山東臨沂"/>
  <cike name="孤獨刺客" pass="123" sex="男士" age="20" img="man2.gif" fatie="0" exp="20" homepage="" email="gdcike@163.com" oicq="" qianming="風雲他是豬!吭大爺做關稅區的斑竹!" address="山東臨沂"/>
  <plgirl name="千千純子" pass="123" sex="女士" age="20" img="woman1.gif" fatie="0" exp="0" homepage="" email="" oicq="" qianming="" address=""/>
</alluser>
]
這是本例所採用的XML儲存結構,不難看出一個標籤即包含了一個會員的所有資訊,標籤名即是“使用者帳號”,其中name=暱稱、pass=密碼、sex=性別……,其中“使用者帳號”必須保證是唯一的,而且必須限制為英文字母或英文字母后邊帶數字,關於XML的檔案結構及資料一定要求符合XML文檔規範及命名規範,若此後在程式中使用者所提交資料處理不託,或可導致資料泄露,或該user.xml即宣告報廢,必須手工尋找更正,否則無法正常存取

論壇文章資料儲存(在主目錄建立一檔案夾,名為data,該data檔案夾今後即儲存所有會員發表的文章,其中文章的檔案名稱是隨機或有規律的如1.xml,2.xml,3.xml,這些檔案儲存體了文章的所有資料包括主題、回複,當然這些檔案的建立、修改、起名、刪除等都是在以後用程式實現的,至於新檔案起名的程式部分要保證其名稱與以有檔案互不衝突即可,檔案名稱可以是無任何規律的,畢竟今後我們不以檔案名稱來實現排序,其單個XML檔案內容結構如下)[
1.xml:
<?xml version="1.0" encoding="gb2312"?>
<?xml-stylesheet type='text/xsl' href='../file.aspx?dex=1.xml'?>
<document>
   <record>
   <anthor>fyw</anthor>
   <title>文章標題</title>
   <date>2003-12-6 3:27:18</date>
   <gengxindate>2003-12-6 3:27:18</gengxindate>
   <body>文章內容

&lt;hr&gt;內容是以過濾HTML等於XML文檔規範相衝突的字元以後的合法內容,標題也需要過濾
</body>
   </record>
</document>

2.xml:
<?xml version="1.0" encoding="gb2312"?>
<?xml-stylesheet type='text/xsl' href='../file.aspx?dex=7908604.xml'?>
<document>
  <record>
    <anthor>fyw</anthor>
    <title>文章標題</title>
    <date>2003-12-6 3:54:59</date>
    <gengxindate>2003-12-6 3:54:59</gengxindate>
    <body>文章內容</body>
    <reply>
      <anthor>cike</anthor>
      <date>2003-12-6 5:53:38</date>
      <gengxindate>2003-12-6 5:53:38</gengxindate>
      <body>1樓回複的內容</body>
    </reply>
    <reply>
      <anthor>plgirl</anthor>
      <date>2003-12-7 5:53:38</date>
      <gengxindate>2003-12-7 5:53:38</gengxindate>
      <body>2樓回複的內容</body>
    </reply>
  </record>
</document>
]
這是本例論壇文章的XML儲存結構,現在我們建立起了會員資料隱藏檔(user.xml)以及論壇文章存放地點和存放結構(data\*.xml),你是否以有所啟發?用程式在這兩者基石上搭橋引線是否真的能夠實現複雜的論壇系統哪?答案是肯定的,只要能通過程式在後台操縱這兩個儲存基地,加以友好的介面,即可小試牛刀
}

第三節:諸葛布陣、將士磨刀

XML資料存放區結構以完成,下面一一列出完成論壇大業所需要的材料
項目包括{
通用函數頁
(建立或一或二這種通用函數頁或DLL或者是使用者控制項,將常用的程式過程、變數、函數放入其中,此後使用可大大節省時間避免重複勞動,這在下一章將有所提及)

遊客與會員的區分
(即是一個session,本例為session("who")值是否存在的判斷,如存在即判斷是會員,如不存在值即為遊客,我們本例不使用cookies儲存使用者資料,遊客許可權自然是只能瀏覽文章,不能發表或回複文章,而會員則可以)

會員註冊
(包含各種表單的頁面,目的是完成向user.xml添加一新的標籤節點(等同添加一新的會員資料),要處理好使用者所提交的資料,方法要用到防止跨站提交、會員帳號(即XML節點頭標籤)要用Regex限制為類似程式變數的文法要求或乾脆只允許使用英文字母、XML節點屬性至少要過濾<>&"'以及斷行符號符號、防止申請的會員帳號以存在user.xml、所有資料英文符號均轉換為小寫格式即不區分大小寫包括使用者帳號和密碼)

會員登陸
(包含使用者帳號輸入框、密碼輸入框和一個登陸按鈕,提交後利用XMLDOM搜尋user.xml是否有匹配的使用者帳號(要特別注意過濾使用者提交的資料,尤其是*號等,這在XMLDOM的搜尋中被認為是萬用字元),如user.xml存有該帳號,即將一個session,本例為session("who"),設值為該使用者帳號,遊客身份即成為會員身份)

會員資料修改
(禁止遊客瀏覽本頁,樣式保持與會員註冊頁的表單基本一樣(但不包含使用者帳號名稱修改的功能),只不過所有表單的值均是預讀了user.xml中匹配session("who")該會員的資訊,使用者修改過後,單擊完成修改按鈕,此時背景程式修改user.xml中該會員對應的節點資料即可)

會員資料顯示
(唯讀頁面,讀取網址參數中對應的會員帳號,顯示會員所有無需保密的資訊)

一個論壇欄目首頁
(即貼文清單,根據URL頁碼參數分頁,顯示data目錄中對應頁碼的所有文章資訊,排序自然根據檔案的修改日期,最新更新的最靠頂,這是開發本論壇中最難的一個項目之一,要謹慎處理,最好實現點對點(即1-10,30-40,100-110)形式分頁的抽取data目錄中的檔案,可以保證最優質的運行速度)

文章顯示頁
(本例的文章顯示是直接在瀏覽器訪問XML檔案,即http://xxx.xxx.xxx/xxx.xml的URL形式訪問,由於僅僅使用靜態XSL控制XML檔案的二層輸出形式是遠遠不夠的,所以我們採取的顯示結構是三層,其順序為(1:開啟XML檔案後尋找xml-stylesheet節點的href所指定的XSL檔案---2:由於目標檔案類型是aspx,我們在目標aspx中根據url參數訪問參考對應的XML檔案資料,控制資料流輸出格式為xsl,叢中很好的整理出理想的xsl樣式表,即起到了中介層的關鍵作用---3:由於aspx輸出的xsl是我們在後台整理過的,其高度的智能、合理,即可以配合XML資料輸出結構複雜的文章顯示頁),期間中介層的開發難度最大,是本論壇系統中最難的一個步驟,簡單的地方是XMLDOM分析抽取目標XML中的節點資料,實現顯示主題、顯示文章作者、顯示文章內容、顯示文章所有回複,但最痛點,本人在著手開發時,就無法解決文章回複的分頁,以及aspx伺服器端控制項和xsl文檔規範相互衝突,可能是本人水平有限,或也是本人原創的這種3層輸出存在本質的缺陷,所謂XML實現資料庫容易,但通過XSL實現超越HTML的理想輸出難)

發表新貼
(禁止遊客發表,該項目即是一個輸入主題的輸入框+內容輸入框+提交按鈕,可以綁定在欄目貼文清單頁下方或建立一個專頁,使用者提交發表後要用server.HTMLEncode()過濾使用者所提交的資料,而後用程式建立XML檔案、給XML檔案起名、整理XML檔案的檔案格式如第二節所寫的格式、向節點內寫入過濾後的資料、修改user.xml對應的發貼會員的節點實現積分+2和發貼數+1,用cookies限制7秒內禁止多次提交灌水)

回複新貼
(禁止遊客回複,該頁可綁定文章顯示頁下方或建立一個專業,提供一內容輸入框+提交按鈕,提交後如發表新貼過程類同,要進行資料過濾,而後在對應的文章儲存XML檔案中插入一reply節點,在該節點中建立用於儲存回複作者名稱、回複內容、回複日期、回複更新日期等節點,修改user.xml對應的發貼會員的節點實現積分+1和發貼數+1,用cookies限制7秒內禁止多次提交灌水)

版主管理功能
(要實現密碼驗證,判斷禁止遊客及會員使用,可選的後台管理功能有獎勵會員積分、減少會員積分、刪除會員、修改任何文章、刪除任何文章,甚至可以考慮諸多封IP、置頂、鎖定、封版主等等進階功能)
}

第四節:君臨沙場、錦囊相助

通過以上三節修鍊,君若仔細攻讀,定已胸有成竹,躍躍欲試,此時想必已經動起手來,或者是思路很清晰卻不知程式該如何寫,若真是如此,不必急噪,筆者先將平生所學一些常用“兵法”一一列出,定可使汝茅塞頓開

1:錯誤提示函數(需要時使用,可彈出對話方塊給與使用者錯誤提醒,而後自動退回上一頁,此函數建議儲存為一通用檔案,需要時<!--#include file="publicfun.aspx"-->一下即可使用)

<script language=vb runat='server'>
sub t2(tstr2 as string)
response.write (replace("<script language=vbs> msgbox " & chr(34) & tstr2 & chr(34) & ",16," & chr(34) & "錯誤提示" & chr(34) & ":history.back()&lt;/script>","&lt;","<")):response.end
end sub
</script>

2:一般資料檢測函數(修改XML標籤屬性時建議使用,用於一般檢測,至於使用者帳號等還需要更嚴密的資料過濾)

<script language=vb runat='server'>
sub jiancha(requeststr as string)         '本例過濾'"<>&*,如有疏漏請補之
dim array1(5) as string
array1(0)="'":array1(1)=chr(34):array1(2)="<":array1(3)=">":array1(4)="&":array1(5)="*"
dim tempi as integer
for tempi=0 to ubound(array1)
if instr(requeststr,array1(tempi))<>0 then response.write (replace("<script language=vbs> msgbox " & chr(34) & "參考資料 " & requeststr & " 不可以含有禁止符號 [" & array1(tempi) & "] ,自動返回請更正" & chr(34) & ",16," & chr(34) & "錯誤提示" & chr(34) & vbcrlf & "history.back()&lt;/script>","&lt;","<")):response.end
next
end sub
</script>

3:asp.net拒絕跨站提交注入(可在會員註冊、會員修改頁等表單較多的頁使用)

<%
if lcase(mid(request.ServerVariables("HTTP_REFERER"),8,len(request.ServerVariables("SERVER_NAME"))))<>lcase(request.ServerVariables("SERVER_NAME")) then t2("拒絕跨站提交!")
%>

4:向目標XML檔案添加新節點

<%@import namespace='system.xml'%>
<%
dim userdom1=new xmldocument,userdom2,userdom3
userdom1.load (server.mappath("user.xml"))          '裝載需要操作的XML檔案
userdom2=userdom1.selectsinglenode("alluser")       '操作遊標指向alluser節點,控制代碼給userdom2變數
userdom3=userdom1.createElement("fyw")              '新建立一名為fyw的節點,並將控制代碼給userdom3變數
userdom3.setAttribute("name","風雲舞")              '為userdom3添加節點屬性,新屬性名稱為name,值為風雲舞
userdom3.setAttribute("pass","123")
userdom3.innerText="測試"                           '設定userdom3節點所包含的資料
userdom2.AppendChild(userdom3)                      'userdom2即alluser節點下添加userdom3所描述的fyw節點
userdom1.save (server.mappath("user.xml"))          '將變動後的新XML資料儲存到user.xml
%>

5:修改XML節點

<%@import namespace='system.xml'%>
<%
dim userdom1=new xmldocument,userdom2
userdom1.load (server.mappath("user.xml"))
userdom2=userdom1.selectsinglenode("alluser").getElementsBytagname("fyw")  '操作遊標指向alluser節點下的fyw節點
userdom2(0).setAttribute("name","風雲舞")           '設定fyw節點數組的第一個,將其name屬性值修改為風雲舞
userdom2(0).innerText="測試"                        '設定fyw節點數組的第一個,將其所包含的資料改為測試
userdom1.save (server.mappath("user.xml"))          '將變動後的新XML資料儲存到user.xml
%>

6:尋找判斷XML節點是否存在

<%@import namespace='system.xml'%>
<%
dim userdom1=new xmldocument
userdom1.load (server.mappath("user.xml"))          '裝載需要操作的XML檔案
'以下正是本人為什麼要用“使用者帳號”標識使用者唯一身份的目的,尋找方便呀:)
if userdom1.selectsinglenode("alluser").getElementsBytagname("fyw").count<>0 then t2("fyw節點以存在")
%>

7:大量新增XML節點(在編寫回複文章時,用第4例提到的方法一個一個填加節點很麻煩,這時可以考慮用此方法批量填加)

<%@import namespace='system.xml'%>
<%
dim filedom=new xmldocument,filedom2
filedom.load(server.mappath("data\" & request.querystring("dex")))  'request.querystring("dex")=6.xml
filedom2=filedom.createElement("reply")
'以下這種方法很方便,而且對XML檔案的結構排版也很好,合理的空格和斷行符號可以表現良好的XML文檔結構
filedom2.innerXml=vbcrlf & "      <anthor>" & session("who") & "</anthor>" & vbcrlf & "      <date>" & now & "</date>" & vbcrlf & "      <gengxindate>" & now & "</gengxindate>" & vbcrlf & "      <body>" & neirong.value & "</body>" & vbcrlf & "      "
filedom.selectsinglenode("document/record").appendChild(filedom2)
filedom.save(server.mappath("data\" & request.querystring("dex")))  'request.querystring("dex")=6.xml
%>

8:刪除XML節點

<%@import namespace='system.xml'%>
<%
dim userdom1=new xmldocument,userdom2
userdom1.load (server.mappath("user.xml"))
userdom1.DocumentElement.RemoveChild (userdom1.selectsinglenode("alluser/fyw"))  '刪除alluser節點下的所有fyw節點
userdom1.save (server.mappath("user.xml"))
%>

9:建立新的XML檔案(可以建立任何類型尾碼的檔案,不局於XML檔案)

<%@import namespace='system.io'%>
<%
dim newfile=new StreamWriter(server.mappath("data\" & new DirectoryInfo(server.mappath("data")).getfiles().length+1 & ".xml"),false,System.Text.Encoding.Default)
'以上我們指定預設編碼方式為System.Text.encoding.default,或者可改為System.Text.encoding.GetEncoding("gb2312"),不然將以UTF8編碼那樣XML含有中文就無法正常工作了
newfile.write ("<?xml version=" & chr(34) & "1.0" & chr(34) & " encoding=" & chr(34) & "gb2312" & chr(34) & "?>" & _
vbcrlf & "<?xml-stylesheet type='text/xsl' href='../file.aspx?dex=" & filelength+1 & ".xml'?>" & vbcrlf & _
"<document>" & vbcrlf & "   <record>" & vbcrlf & "   <anthor>" & session("who") & "</anthor>" & vbcrlf & _
"   <title>" & server.HTMLEncode(biaoti.value) & "</title>" & vbcrlf & "   <date>" & now & "</date>" & vbcrlf & _
"   <gengxindate>" & now & "</gengxindate>" & vbcrlf & "   <body>" & server.HTMLEncode(neirong.text) & "</body>" & vbcrlf & _
"   </record>" & vbcrlf & "</document>")
newfile.close:newfile=nothing
%>

10:刪除指定檔案

<%@import namespace='system.io'%>
<%file.delete(server.mappath("data\2.xml"))%>

11:用cookies實現7秒內不許重複灌水

<%
if not request.cookies("lshdicbbs") is nothing then
if isdate(request.cookies("lshdicbbs")("guanshui"))=false then response.cookies("lshdicbbs")("guanshui")=now
if datediff("s",request.cookies("lshdicbbs")("guanshui"),now)<7 then response.write ("7秒內禁止重複發貼灌水"):response.cookies("lshdicbbs")("guanshui")=now:response.end
end if
response.cookies("lshdicbbs")("guanshui")=now
%>

12:用Regex限制使用者提交的資料必須為英文字母(有興趣可延伸強化為支援英文字母+數位形式)

<%
dim name1=request.form("username")
if regex.replace(name1,"[a-z]+","",RegexOptions.IgnoreCase)<>"" then t2("帳號名必須使用A-Za-z範圍的英文字母")
%>

13:擴充提示工具(早先原創指令碼,可根據需要修改)

<div style='position:absolute;left:0;top:0;border-bottom:1 solid green;border-right:1 solid green;border-left:1 solid cccccc;border-top:1 solid cccccc;display:none;z-index:500;background-color:#FFF7FF;padding:2;white-Space:nowrap;table-Layout:fixed;' id=showdiv></div>
<script>
var oldtext="加速變數",colors1=new Array("#FFECD5","#FFF7FF","#FFFFEB","white","#F5FFEB","#EEFAFF","#FFFFEE","#EDFFFC")
function document.onmousemove(){
try{
if(event.srcElement.getAttribute('lshdic'))
{
showdiv.style.left=event.x-3;showdiv.style.top=event.y+document.body.scrollTop+18;if(event.srcElement.lshdic!=oldtext){oldtext=event.srcElement.lshdic;showdiv.innerText=oldtext;showdiv.style.backgroundColor=colors1[Math.round(Math.random()*colors1.length)]};if(showdiv.style.display=='none')showdiv.style.display=''
}else{if(showdiv.style.display=='')showdiv.style.display='none';}}catch(e){}
}
</script>
<a href="http://www.lshdic.com" lshdic='歡迎訪問作者網站'>藍麗網</a>
<a href="http://www.lshdic.com/bbs" lshdic='歡迎訪問藍麗技術論壇&#13;&#13;2003-12-6 10:31:32'>藍麗技術論壇</a>

第五節:神劍在此、贈我知音

經過以上4個章節的艱苦學習,我相信您以基本瞭解了如何用背景程式結合XML資料庫實現複雜的論壇和系統,但通讀N邊也起不了實際作用,你必須著手去做,才能在實踐中總結出自己的經驗,本文章僅僅是個輔助參考而已

由於時間有限,本人只能將親手開發的ASP。NET版本的XML無資料庫論壇(全稱:藍麗NetXml無資料庫論壇1.0)奉獻給各位研究,由於本人的ASP。NET虛擬空間有點問題,無法提供線上示範,現僅提供全部原代碼下載(以上13例原代碼多數採摘於本系統中),地址:http://www.lshdic.com/download/netxmlbbs.rar,下載後可參考說明檔案,在您自己的ASP。NET伺服器上測試。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.