<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    網站開發

    asp.net
    隨筆 - 30, 文章 - 0, 評論 - 9, 引用 - 0
    數據加載中……

    2006年11月8日

    提高網站在Google中的排名 ——面向搜索引擎的網站設計

    Google排名優化-面向搜索引擎的網站設計


    內容摘要:
    目前中文網站在整個互聯網中的影響還比較小,這主要是由于中文網站總體的水平(技術上,內容上)都還相對落后造成的,最主要的表現有:

    1. 行業知識:不知道搜索引擎對吸引的新用戶的重要性,在搜索引擎排名服務中追求“傻瓜相關”,購買一些其實沒有太多實際意義的行業關鍵詞。其實能夠用戶輸入的關鍵詞越多,其目標性越強,這樣的客戶價值越高。用戶能夠直接定位到產品具體內容頁比到網站首頁有價值的多;
    2. 發布技術:網站的網頁進入Google的索引量非常小,主要是由于大量使用動態網頁造成的。需要將動態頁面鏈接改寫成靜態鏈接
    3. 頁面設計:頁面標題重復,關鍵詞不突出,過渡使用JavaScript腳本/圖片/Flash等不適合搜索引擎索引的非文本形式;
    而以上這些問題的根本原因還是網站自身缺乏日志統計分析造成:因此無法看到SEO對網站自身產生的巨大影響。

    SEO的目的是通過一些簡單的策略,讓網站自身的水平在互聯網中有一個真實的體現。
    網站結構設計中面向搜索引擎的優化注意事項包括:

    (注意:本網站設計本身就利用了其中一些方法)。

    什么是PageRank

    Google等新一帶搜索引擎的優勢之一在于不僅索引量很大,而且還將最好的結果排在搜索結果的最前面,具體的原理可以參考Google の秘密 - PageRank 徹底解説一文,PageRank簡單的說類似于科技論文中的引用機制:誰的論文被引用次數多,誰就是權威。在互聯網上PageRank就是基于網頁中相互鏈接關系的分析得出的。

    此外,從計算方法角度闡述PageRank機制還有這篇文章:http://pr.efactory.de/里面有更詳細的PageRank算法說明和各種清晰的小型個案分析:

    比如:子頁中導航條的重要性
    B <=> A => C  
    Vs  
    B <=> A <=> C   (好)

    頁面數量因素:
    B <=> A <=> C
    Vs
    F <=\   /=> G
    B <=> A <=> C   (好)
    D <=/   \=> E

    一個意想不到的結論:
    (B <=> A <=> C)      ( E <=> D <=> F)
    Vs
    (B <=> A <=> C)  <=> ( E <=> D <=> F)
    PageRank升高的只是被鏈接的2個首頁A和D,而網站子頁面的PageRank平均會略有下降。同時:一個網站進入Google的索引量越大其受類似因素影響越小。
    PageRank不對稱的頁面互鏈:
    Google會用BadRank之類的算法進行糾正,而且一個網頁著有來自“與其自身不相稱”的高PageRank站點的鏈接,而自身又缺少足夠數量和質量的反相鏈接的話,其PageRank會自動降低為0,A(pr=7) <=> B(pr=0)
    簡單的說就是:偶爾要被權威站點反相鏈接不算數,要被足夠多的權威站點引用才能提高自身網頁的PageRank。
    Web超鏈分析算法綜述(南京大學論文) 更多論文可以通過搜索:“filetype:pdf google pagerank anchor text bayesian”得到

    鏈接就是一切

    在互聯網的海洋中,最重要的就是互聯互通,不被其他網站引用的網站就是“信息孤島”。“酒好也怕藏的深”,也許這話說起來有點像垃圾郵件廣告,但事實就是這樣。所以如果做網站的目的不是孤芳自賞,就需要積極的推廣自己的網站。
    通過搜索引擎推廣自己需要注意以下幾個方面:

    1. 以量取勝:不一定加入傳統門戶網站的分類目錄才是網站推廣,來自其他網站的任何反相鏈接都是有用的
      網站推廣比較經典的方式就是加入比較大型門戶網站的分類目錄,比如:Yahoo!,dmoz.org等。其實這里有一個誤區:不一定非要加入大型網站的分類目錄才是網站推廣,因為現在搜索引擎已經不再只是網站目錄的索引,而是更全面的網頁索引,所以無論來自其他網站任何地方的反相鏈接都是非常有價值的,哪怕是出現在新聞報道,論壇,郵件列表歸檔中。Blogger(Weblog的簡稱)們也許最深刻地理解了“鏈接就是一切”這句話的含義,由于Blog的內容之間有大量的相互鏈接(他們之間利用RSS很容易進行鏈接大量傳播),因此最經常被引用的Blog頁面在搜索引擎中的排名往往比一些大型商業網站的頁面還要高。而WIKI這樣的文檔管理系統更加突出了良好結構,良好引用的特征。而目前很多網站通過在各種WIKI/留言簿中灌注垃圾留言的方法,這種方式是非常不可取的。這種鏈接不穩定:
    2. 以質取勝:被PageRank高的網站引用能更快地提高PageRank
      數量只是關鍵因素之一,來自PageRank高的頁面的鏈接還能更快的提高被鏈接目標的PageRank,我只是將一些文章投稿在了ZDNet中國上,由于頁面上有文章出處鏈接,相應網頁和網站整體的PageRank過了一段時間后就有了很大的提升。有時候被什么樣的網站引用有時候比引用次數多更重要。這里我要特別感謝的是,當時ZDNet中國是唯一遵循了我的版權聲明的要求表明了文章出處,并且有反相鏈接的網站。
      按照這個原則:能夠名列Yahoo!和DMOZ這樣的大型權威目錄的頭2層是非常有價值的。
    3. 了解搜索引擎的"價值觀":
      Lucene簡介這篇文章被Jakarta.apache.org的lucene項目引用以后,這篇文章就成為了所有頁面中PageRank最高的頁面,而Google支持的一些項目,比如:Folding@Home,讓我一直懷疑他們對政府,教育和非盈利組織的站點有特別加分,畢竟.org .edu才代表了互聯網的實質:分權和共享。
      但更合理的解釋是:.org很多都是開放技術平臺的開發者,他們會在首頁這樣的地方加入Powered By Apache, Power by FreeBSD之類的鏈接表示對其他開源平臺的尊重,所以象Apache, PHP, FreeBSD這樣的開源站點在GOOGLE中都有非常高的PageRank。而在.edu這些站點中,很多都是學術性比較強的文檔,以超鏈接形式標明參考文獻的出處已經成為一種習慣,而這也無疑正是PageRank最好的依據。
      注意:不要通過Link Farm提高自身的站點排名:Google會懲罰那些主動鏈接到Link Farm站點以提高自身排名站點,相應站點的頁面將不會被收入到索引中。但如果你的頁面被別的Link Farm鏈接了也不必擔心,因為這種被動的鏈接是不會被懲罰的。
    4. 不要吝嗇給其他網站的鏈接:如果一個網頁只有大量的進入鏈接,而缺乏導出鏈接,也會被搜索引擎認為是沒有價值的站點。保證你的網站能夠幫助搜索引擎更準確地判斷哪些是對用戶最有價值的信息,也就是說如果你的網站只有外部反向鏈接而沒有導出鏈接的話,也會對你的網站在搜索結果中的表現帶來負面影響。當然網站中連一個導出鏈接都沒有的情況非常罕見,除非你是刻意這么做。正常情況下大家都會自然地在網頁中加上一些其他網站的鏈接,帶領訪問者去到我們認為重要或能夠提供更多有價值信息的地方,

    另外在推廣自己網站之前也許首先需要了解自己網站目前在一些搜索引擎中的知名度,原理非常簡單,可以參考如何評價網站的人氣一文。

    網站推廣只是手段,如何突出內容、讓需要相關信息的用戶能夠盡快的找到你的網站才是目的,PageRank高并不代表像Yahoo!這樣的門戶站點就能在所有搜索結果中排名靠前,因為搜索引擎的結果是搜索關鍵詞在頁面中的匹配度和頁面的PageRank相結合的排名結果。因此第二個要點:如何突出關鍵詞。

    如何突出關鍵詞:面向主題(Theme)的關鍵詞匹配

    1.  Theme Engine正在逐步超過PR,成為結果排序中更主要的因素,可以比較一下以下現象:
      • 為什么查“新聞”,“汽車”之類的文字,各種門戶網站的首頁不在第一位?要知道他們的頁面中都有相應頻道的鏈接文字的
      • 一篇新聞頁面中,搜索引擎如何不通過模板匹配,自動將新聞的主體和頁面中的頁頭,欄目導航條,頁尾等部分的內容區分開的?
      其實以上問題都可以歸結為網頁內容摘要的提取策略和關鍵詞在其中的命中:
      首先將能夠描述一個頁面內容的分成以下幾種類型:
      1. 鏈入文字描述:inbound link text
        http://www.searchenginedictionary.com/terms-inbound-link.shtml
      2. HTML頁面標題:title 好標題一般會將頁面中最重要的關鍵詞放在最前面,比如:ABC-10型吸塵器 - XX家電城
      3. HTML內容主體:content text
      4. 鏈出文字:outbound link text
      如果按照以下規則:
      一個頁面中關鍵詞命中權重:鏈入文字 > HTML標題文字 > HTML頁面主體內容 >> 出鏈文字,以上現象就比較好解釋了。
      鏈入文字是頁面上看不見的,但鏈入文字對被鏈接頁面有巨大的作用:在現代搜索引擎在關鍵詞匹配的過程中,匹配的過程不只看當前頁面的內容摘要:很大程度上,不只看這個網頁自己說自己有什么內容,還要看別人如何鏈接時,如何描述你的網站別人怎么稱呼你,比你自己說自己更重要。。
      比如查:“世界衛生組織”,返回結果中有 http://www.who.int/ 而這個頁面中是沒有中文的,之所以能匹配上,是因為很多鏈接它的中文網站使用了:<a >世界衛生組織</a>,所以,這個頁面中不存在的中文關鍵詞也成為了頁面摘要的一部分。這樣一想,就可以知道鏈出鏈接的文字其實是為被鏈接的子頻道首頁或者內容詳情頁服務的。對自身頁面的關鍵詞密度只有負面的影響,這也是Google建議一個頁面中鏈接不要超過100個的原因:他根本不索引100個鏈接以后的內容。按照以上規則,搜索引擎將一篇新聞詳情頁中的新聞內容提取出來就是把頁面上所有帶HTTP鏈接的文字都去掉,就是新聞的內容部分了,更精確一些可以通過取最長文本段落等策略實現;而很多網站首頁或頻道首頁中幾乎全部都是鏈接,經過搜索引擎分析的結果就是:什么內容也沒有,能夠被命中的關鍵詞僅僅是別人鏈接你用的“網站首頁”和頻道標題Title中的站點名稱等的幾個關鍵詞,而頁面中其他的文字則遠遠不如相應子頻道和具體內容頁面的匹配度高,而搜索引擎能夠通過以上規則,讓用戶更快的直接定位到有具體內容的內容詳情頁面。因此希望通過一個首頁,盡可能多的命中所有希望推廣的關鍵詞是不可能的。讓網頁盡可能多的進入搜索引擎的索引,然后把握好整個網站的主題風格是非常重要的,讓網站的主題關鍵詞能夠比較均勻的按照金字塔模式分布到網站中可以參考:網站的主題金字塔設計          網站名稱(用戶通過1-2個抽象關鍵詞)
               /       \
          子頻道1   子頻道2 (用戶通過2-3個關鍵詞命中)
         /    \      /    \
      產品1  產品2 文章1 文章2 (用戶通過3-4個關鍵詞命中:這種用戶最有價值)

    2. 不要空著標題:空著<title></title>無異于浪費了最有價值的一塊陣地;
      不要使用meta keywords/description
      傳統的頁面中,HTML頁面中會有類似以下的隱含信息,用于說明當前網頁的主要內容關鍵字:
      <header>
          <meta name="keyword" content="mp3 download music...">
      </header>
      后來由于這種人工添加關鍵詞的方式被濫用,大量網頁中為了提高被搜索引擎命中的概率,經常添加一些和實際網頁內容無關的熱門關鍵比如:“music mp3 download”等,所以新一代的搜索引擎已經不再關心頁面頭文件中的人工meta keyword聲明,而頁面標題在搜索引擎的關鍵詞的命中命中過程中往往有著更高的比重,如果一個關鍵詞在標題中命中會比在頁面中命中有更高的得分,從而在相應的搜索結果排名中更靠前。
    3. 標題長度和內容:不要過長,一般在40個字(80個字節)以內,并充分突出關鍵詞的比重;
      如果更長的標題搜索引擎一般會忽略掉,所以要盡可能將主要關鍵詞放在標題靠前的位置。省略掉不必要的形容詞吧,畢竟用戶主要通過名詞來找到需要的內容。標題內容:盡量用一些別人可以通過關鍵詞找到的字眼(也別太過頭,如果標題中的字眼超過1半內容中都沒有,有可能被搜索引擎排除出索引),因此基于web日志中來自其他搜索引擎的關鍵詞查詢統計非常必要。
    4. 如果網頁很多的話,盡量使用不同的網頁標題,爭取讓自己網站的內容更多的進入搜索引擎索引范圍;
      因為搜索引擎會根據頁面內容的相似度把一些內容當成重復頁面排除出索引范圍;
      http://www.chedong.com/phpMan.php是我的網站上的一個小應用:一個web界面的unix命令手冊(man page),在以前的設計中所有動態頁面使用的都是同樣的標題:"phpMan: man page /perldoc /info page web interface" ,Google索引了大約3000多個頁面,后來我將頁面標題改成了"phpMan:  [命令名]"這樣的格式,比如:"phpMan: ls",這樣大部分動態頁面的標題就都不一樣了,一個月后Google從這個頁面入口索引了大約6000個頁面。因此,如果網站中很多網頁都使用相同的標題,比如:“新聞頻道”,“論壇”,這些頁面中很大一部分就會被排重機制忽略掉。
    5. 除了<title></title>外,還可以用<h1></h1>標題行突出內容主題,加強標題的效果;
      在我的網站設計中:我會把用<h1>[標題]</h1>這樣的模板把標題突出顯示,而不是通過改變字體的方式突出標題。

    其他網站設計提示

    1. 靜態鏈接:Blog網站另外一個優勢在于其網頁是靜態鏈接:動態網頁占到整個互聯網內容的90%以上。各個搜索引擎其實能夠表現的都只不過是互聯網的冰山一角(3-5%),不同的只是誰讓優質網頁排名靠前的策略更優秀而已:大部分搜索引擎都認為靜態鏈接的網頁是優質網頁,Google在優先抓取索引的網頁中70%以上是不帶參數鏈接的靜態網頁。而且即使同樣的內容,靜態網頁也會比動態網頁權重高:很容易理解:query?a=1&b=2這樣的鏈接由于參數順序顛倒的query?b=2&a=1完全相同。盡量使用靜態網頁:目前能夠動態網頁進行全面的索引還比較難,而即使是Google也更不會索引所有的內容,因此很少會對參數超過2個的動態網頁進行進一步的抓取和分析。以下是一個phpBB論壇頁面返回的HTTP頭信息:
      HTTP/1.1 200 OK
          Date: Wed, 28 Jan 2004 12:58:54 GMT
          Server: Apache/1.3.29 (Unix) mod_gzip/1.3.26.1a PHP/4.3.4
          X-Powered-By: PHP/4.3.4
          Set-Cookie: phpBB_data=a%3A0%3A%7B%7D; expires=Thu, 27-Jan-2005 12:58:54 GMT; path=/;
          Set-Cookie: phpBB_sid=09f67a83ee108ecbf11e35bb6f36fcec; path=/;
          Content-Encoding: gzip
          Cache-Control: private, pre-check=0, post-check=0, max-age=0
          Expires: 0
          Pragma: no-cache
          Connection: close
          Content-Type: text/html
          
      為了避免隱私問題:Googlebot可以通過對頁面http header中的session id和session cookie進行一些甄別,這樣很多需要認證信息的論壇內容就無法進入索引了。
      總體上說Google喜歡新的,靜態的內容。因此無論從效率上講還是方便搜索引擎收錄:使用內容發布系統將網站內容發布成靜態網頁都是非常必要的,從某種程度上說google friendly = anonymous cache friendly。
      比如:http://www.chedong.com/phpMan.php/man/intro/3
      比http://www.chedong.com/phpMan.php?mode=man&parameter=intro&section=3這樣的鏈接更容易進入搜索引擎的索引。而且在URL中的命中也能突出關鍵詞。
    2. 能夠進入Google索引的頁面數量越多越好。用類似以下的腳本可以統計自己的網站被搜索引擎索引的情況。
      #!/bin/sh
          YESTERDAY=`date -d yesterday +%Y%m%d`
          # for FreeBSD: YESTERDAY=`date -v-1d +%Y%m%d`
          LOG_FILE='/home/apache/logs/access_log'
          grep -i Googlebot $LOG_FILE.$YESTERDAY|awk '{print $7}' |sort | uniq -c | sort -rn > spider/$YESTERDAY.googlebot.txt
          grep -i baiduspider $LOG_FILE.$YESTERDAY|awk '{print $7}' |sort | uniq -c | sort -rn > spider/$YESTERDAY.baiduspider.txt
          grep -i msnbot $LOG_FILE.$YESTERDAY|awk '{print $7}' |sort | uniq -c | sort -rn > spider/$YESTERDAY.msnbot.txt
          grep -i inktomi $LOG_FILE.$YESTERDAY|awk '{print $7}' |sort | uniq -c | sort -rn > spider/$YESTERDAY.inktomi.txt
          grep -i openbot $LOG_FILE.$YESTERDAY|awk '{print $7}' |sort |uniq -c | sort -rn > spider/$YESTERDAY.openbot.txt
          
    3. 網站目錄結構要扁平,因為每深一級目錄,PAGERANK降低1-2個檔次。假設首頁是3,其子可能目錄就是1了,更深可能就無法列入評級范圍了。
    4. 表現和內容的分離:“綠色”網頁
      網頁中的javascript和css盡可能和網頁分離,一方面提高代碼重用度(也方便頁面緩存),另外一方面,由于有效內容占網頁長度的百分比高,也能提高相關關鍵詞在頁面中的比重也增加了??傊瑧摴膭钭裱瓀3c的規范,使用更規范的XHTML和XML作為顯示格式便于內容更長時間的保存。
    5. 讓所有的頁面都有能夠快速入口:站點地圖,方便網頁爬蟲(spider)快速遍歷網站所有需要發布的內容。如果首頁就是用Flash或圖片進入的話,無異于將搜索引擎拒之門外,除了UI設計的用戶友好外,spider friendly也是非常重要的。
    6. 保持網站自身的健康:經常利用壞鏈檢查工具檢查網站中是否有死鏈。
    7. 保持網頁內容/鏈接的穩定性和持久性:在搜索引擎索引中網頁存在的歷史也是一個比較重要的因素,而且歷史比較久的網頁被鏈接的幾率越高。為了保證自己網頁能夠被比較持久的被其他網站的頁面引用,如果自己網頁中有鏈接更新時,最好能保留舊的頁面并做好鏈接轉向,以保持內容的連續性。要知道,把一個網站和內容在搜索引擎中的排名“培養”的很高是一件非常不容易的事情,誰都不希望好不容易自己的內容被別人找到了,點擊卻是“404 頁面不存在”吧,因此站點管理員對自身站點error.log的分析也是非常必要的。
    8. 文件類型因素:Google有對PDF, Word(Power Point, Excel), PS文檔的索引能力,由于這種文檔的內容比一般的HTML經過了更多的整理,學術價值一般比較高,所以這些類型的文檔天生就比一般的HTML類型的文檔 PageRank要高。因此,對于比較重要的文檔:技術白皮書,FAQ,安裝文檔等建議使用PDF PS等高級格式存取,這樣在搜索結果中也能獲得比較靠前的位置。
    9. 常常能發現門戶站點的一條新聞往往比其他站點的首頁排名還要靠前。因此一個站點總體PageRank提高了以后,往往自身一些并不重要的內容也會被同那些高PageRank的內容一起帶入被搜索引擎優先查詢的列表中。這樣經常造成很多大的開發站點的郵件列表歸檔往往比其他站點的首頁PageRank還要高。

    知己知彼——站點訪問統計/日志分析挖掘的重要性

    網站設計不僅僅只是被動的迎合搜索引擎的索引,更重要是充分利用搜索引擎帶來的流量進行更深層次的用戶行為分析。目前,來自搜索引擎關鍵詞統計幾乎是各種WEB日志分析工具的標準功能,相信商業日志統計工具在這方面應該會有更強化的實現。WEB日志統計這個功能如此重要,以至于新的RedHat 8中已經將日志分析工具webalizer作為標準的服務器配置應用之一。

    以Apache/webalizer為例,具體的做法如下:
    1. 記錄訪問來源:
      在Apache配置文件中設置日志格式為combined格式,這樣的日志中會包含擴展信息:其中有一個字段就是相應訪問的轉向來源: HTTP_REFERER,如果用戶是從某個搜索引擎的搜索結果中找到了你的網頁并點擊過來,日志中記錄的HTTP_REFERER就是用戶在搜索引擎結果頁面的URL,這個URL中包含了用戶查詢的關鍵詞。
    2. 在webalizer中缺省配置針對搜索引擎的統計:如何提取HTTP_REFERER中的關鍵詞
      webalizer中缺省有針對yahoo, google等國際流行搜索引擎的查詢格式:這里我增加了針對國內門戶站點的搜索引擎參數設置
      SearchEngine yahoo.com p=
      SearchEngine altavista.com q=
      SearchEngine google.com q=
      SearchEngine    sina.com.cn word=
      SearchEngine    baidu.com   word=
      SearchEngine    sohu.com    word=
      SearchEngine    163.com q=

    通過這樣設置webalizer統計時就會將HTTP_REFERER中來自搜索引擎的URL中的keyword提取出來,比如:所有來自 google.com鏈接中,參數q的值都將被作為關鍵詞統計下來:,從匯總統計結果中,就可以發現用戶是根據什么關鍵詞找到你的次數,以及找到你的用戶最感興趣的是那些關鍵詞等,進一步的,在webalizer中有設置還可以將統計結果倒出成CSV格式的日志,便于以后導入數據庫進行歷史統計,做更深層次的數據挖掘等。

    以前通過WEB日志的用戶分析主要是簡單的基于日志中的訪問時間/IP地址來源等,很明顯,基于搜索引擎關鍵詞的統計能得到的分析結果更豐富、更直觀。因此,搜索引擎服務的潛在商業價值幾乎是不言而喻的,也許這也是Yahoo! Altavista等傳統搜索引擎網站在門戶模式后重新開始重視搜索引擎市場的原因,看看Google的年度關鍵詞統計就知道了,在互聯網上有誰比搜索引擎更了解用戶對什么更感興趣呢?

    請看本站的反相鏈接統計:http://www.chedong.com/log/2003_6.log
    需要注意的是:由于Google針對Windows 2000中的IE使用的是UTF-8方式的編碼,因此很多統計有時候需要在UTF-8方式下查看才是正確字符顯示。從統計中能夠感受到:在使用水平比較高的IT開發人員中Google已經成為最常用的搜索引擎。而使用百度的用戶也已經大大超過了傳統的搜狐,新浪等門戶站點,因此傳統門戶網站在搜索引擎上的優勢將是非常脆弱的。而從技術的發展趨勢來看,以后還會有更多的利用互聯網媒體做更深層次數據挖掘的服務模式出現:

     

    轉載自cnblog.org——“突發”文字可能揭示社會趨勢

    在“新科學家”(New Scientist)在線雜志上,公布了康奈爾大學的一個新研究成果,引人注目,也許與Google 收購Pyra 的動機有關。

    這所大學的計算機科學家 Jon Klenberg 開發了一個計算機算法,能夠識別一篇文章中某些文字的“突發”增長,而且他發現,這些“突發”增長的文字可以用來快速識別最新的趨勢和熱點問題,因此能夠更有效地篩選重要信息。過去很多搜索技術都采用了簡單計算文字/詞組出現頻率的方法,卻忽略了文字使用增加的速率。

    Jon 特別指出,這種方法可以應用到大量Weblog上,以跟蹤社會趨勢,這對商業應用也很有潛力。例如,廣告商可以從成千上萬的個人Blog 中快速找到潛在的需求風尚。而且只要Blog 覆蓋話題范圍足夠大(實際上發展趨勢確實如此),這項技術對政治、社會、文化和經濟等領域也都會有實際意義了。

    雖然Google 新聞的內部算法至今沒有公開,但是人們猜測這種完全由機器所搜集的頭條新聞應當不是Google搜索引擎中慣用的鴿子算法,很可能與這種“突發”判斷算法有關。如此說來,Google收購Blog工具供應商的舉動確實還有更深層次的遠見了

    - NewScientist.com news,
    - 還沒有寫完這些介紹,在 SlashDot 上也看到了很多有關這個發現的討論

    附:Google官方的站點設計指南

    • Make a site with a clear hierarchy and text links. Every page should be reachable from at least one static text link.  讓網站有著清晰的結構和文本鏈接,所有的頁面至少要有一個靜態文本鏈接入口
      批注:盡量不要用圖片和JAVASCRIPT
    • Offer a site map to your users with links that point to the important parts of your site. If the site map is larger than 100 or so links, you may want to break the site map into separate pages.
      為用戶提供一個站點地圖:轉向網站的重要部分。如果站點地圖頁面超過100個鏈接,則需要將頁面分成多個頁面。
      批注:索引頁不要超過100個鏈接:SPIDER只考慮頁面中頭100個鏈接
    • Create a useful, information-rich site and write pages that clearly and accurately describe your content.
      用一些有用的,信息量豐富的站點,清晰并正確的描述你的信息。
    • Think about the words users would type to find your pages, and make sure that your site actually includes those words within it.
      想像用戶可能用來找到你的關鍵詞,并保證這些關鍵詞在網站中出現。
      批注:少用“最大”,“最好”之類的形容詞,用用戶最關心的詞,比如:下載,歌星名字,而不是一些抽象名詞。
    • Try to use text instead of images to display important names, content, or links. The Google crawler doesn't recognize text contained in images.
      盡可能使用文本,而不是圖片顯示重要的名稱,內容和鏈接。GOOGLE的機器人不認識圖片中的文字。
    • Make sure that your TITLE and ALT tags are descriptive and accurate.
      保證:頁面的TITLE和ALT標記正確的精確描述
    • Check for broken links and correct HTML.
      檢查壞鏈并修正這些HTML錯誤。
    • If you decide to use dynamic pages (i.e., the URL contains a '?' character), be aware that not every search engine spider crawls dynamic pages as well as static pages. It helps to keep the parameters short and the number of them small.
      如果你打算使用動態頁面:鏈接中包含"?",必須了解:并非所有的搜索引擎的機器人能想對待靜態頁面一樣對待動態頁面,保持動態頁面的參數盡可能的少也會很有幫助。
    • Keep the links on a given page to a reasonable number (fewer than 100).
      讓一個頁面中的鏈接少于100個。
      批注:用lynx -dump http://www.chedong.com 可以模擬從robot角度看到的頁面。其最后有鏈接統計

    輸出類似:

       [1]Google Free Search _______________________________ Google Search
       (_) Search WWW (_) Search chedong.com

       更 新 [2]站點地圖 / Site Map [3]留 言簿 / Guest Book [4]意見反饋 /
       Feed Back
        ...
    References

       Visible links
       1. http://www.google.com/services/free.html
       2. http://www.chedong.com/sitemap.html#sitemap
       3. http://www.chedong.com/guestbook/
       4. http://www.chedong.com/formmail.htm
        ...
       Hidden links:
      50. http://www.chedong.com/bbcweb/
        ...

    搜索引擎的宗旨在于提取互聯網中質量最好的內容提供給用戶,任何有利于幫助用戶獲得相對公正,優質內容的策略都是搜索引擎追求目標。PageRank是一個非常好的策略,但是并非所有策略都是基于非常復雜的算法。
    從搜索引擎看來什么是互聯網中“好”的內容呢?

    • 首先:互聯網大約是8G個網頁,而且以每天2M的速度增長的。其中80%以上是動態網頁,而占總量20%的靜態網頁就是一個相對比較簡單的過濾規則。
    • 其次:用戶友好(User friendly)也是很重要的方面,搜索引擎利用算法幫助提升這些優質網站,包括:通過CSS將內容和表現分離:較少的javascript和frame結構,spider本身也很難深入抓取這些網頁:Javascript和frame結構大部分是廣告。
    • 標題明確:無標題,重復標題或者標題SPAM(類似于:游戲游戲游戲游戲游戲游戲這樣的標題)進行過濾或降低得分頁面大?。阂驗轫撁孢^大會導致用戶下載緩慢,所以很多引擎只計算頁面大小在100k以內的網頁。
    • 鏈接引用:不僅需要有鏈接鏈入,也需要幫助用戶找到其他更有價值的內容;
    • 文件類型:PDF和DOC等專業文檔和來自edu,gov等非贏利網站的內容;
    • 鏈入網站的文字:所有用戶不可見的因素全部被忽略。此外:用戶搜索的行為本身也被Google記錄,可能對目標網站的主題相關度有幫助。

     

    參考資料:

    面向Google搜索引擎的網站設計優化
    http://www.google-search-engine-optimization.com/



    如何評價一個網站的人氣
    http://www.chedong.com/tech/link_pop_check.html

    如何提高網站在Google中的排名——面向搜索引擎的廣告模式
    http://www.chedong.com/tech/google_ads.html

    如何提高網站在Google中的排名——面向搜索引擎的網站鏈接設計
    http://www.chedong.com/tech/google_url.html

    Google不斷改進相應的算法:HillTop
    Hilltop: A Search Engine based on Expert Documents

    Google の秘密 - PageRank 徹底解説
    http://www.kusastro.kyoto-u.ac.jp/~baba/wais/pagerank.html
    這篇文章是在查"Google PageRank"的時候查到的,這篇文章不僅有一個算法說明,也是一個Google的weblog,記錄了很多關于Google的新聞和一些市場動態信息。
    Google 的秘密- PageRank 徹底解說 中文版

    更詳細的PageRank算法說明:
    http://pr.efactory.de/

    WEB日志統計工具AWStats的使用:增加了Unicode的解碼和中國主要門戶搜索的定義
    http://www.chedong.com/tech/awstats.html

    Robots的說明:
    http://bar.baidu.com/robots/
    http://www.google.com/bot.html
    搜索引擎通過一種程序robot(又稱spider),自動訪問互聯網上的網頁并獲取網頁信息。您可以在您的網站中創建一個純文本文件 robots.txt,在這個文件中聲明該網站中哪些內容可以被robot訪問,哪些不可以。

    反Google站點:觀點也很有趣
    http://www.google-watch.org/

    關于Google的WebLog
    http://google.blogspace.com/

    關于Google的HillTop算法

    搜索引擎相關論壇
    http://searchengineforums.com/
    http://searchenginewatch.com
    http://www.webmasterworld.com/

    posted @ 2008-01-04 09:43 風雨兼程 閱讀(262) | 評論 (0)編輯 收藏

    開發電子商務網站對數據庫表的設計

    系統分析

      功能需求分析

      (1):產品展示,按照分類展示全部產品,和對應的相關信息。

      (2):增加產品的展示相關度,諸如最新產品報道,網站的新聞,促銷信息。

      (3):購物車,跟蹤用戶的購物情況

      (4):結算中心:處理用戶帳單,購物處理

      (5):反饋互動區,可以留言

      (6):會員信息模塊,可以注冊

      數據需求分析

      數據庫表設計定為8個表實現:

      ccdot_user{用戶信息表}:

      ------szd_userid[PK]

      ------szd_username[用戶ID]

      ------szd_password[用戶密碼]

      ------szd_name[用戶真是信息]

      ------szd_question[丟失密碼問題]

      ------szd_answer[用戶回答答案,用于找密碼]

      ------szd_sex[性別]

      ------szd_phone[電話]

      ------szd_email[電子郵件]

      ------szd_address[地址]

      ------szd_post[郵編]

      ------szd_province[省份]

      ------szd_city[城市]

      ------szd_mark[標記]

      ccdot_aclass{產品大類}

      ------szd_aclassid[PK]

      ------szd_aclassname[名稱]

      ccdot_bclass{產品小類}

      ------szd_bclassid[pk]

      ------szd_aclassid[關聯大類szd_aclassid]

      ------szd_bclassname[名稱]

      ccdot_poduct{產品信息}

      ------szd_productid[pk]

      ------szd_bclassid[關聯小類的szd_bclassid]

      ------szd_pname[名稱]

      ------szd_pdetail[產品信息]

      ------szd_pprice[一般價格]

      ------szd_pmemderprice[會員價]

      ------szd_pfewprice[差價]

      ------szd_ppicture[圖片]

      ------szd_ptime[添加時間]

      ------szd_stock[產品庫存]

      ------szd_phit[產品點擊次數]

      ------szd_pdetail1[其他產品描述]

      ccdot_news{新聞}

      ------szd_newsid[PK]

      ------szd_title[標題]

      ------szd_content[內容]

      ------szd_time[添加時間]

      ------szd_type[類型]

      ccdot_guest{評論}

      ------szd_gid[PK]

      ------szd_gname[昵稱]

      ------szd_gcontent[留言內容]

      ------szd_productid[關聯產品的主鍵]

      ------szd_gtime[留言時間]

      ------szd_gip[留言者ip]

      ccdot_orderlist{訂單列表}

      ------szd_orderlistid[PK]

      ------szd_orderid[關聯詳細訂單的主鍵]

      ------szd_productid[關聯產品的主鍵]

      ------szd_quantity[所定數目]

      ------szd_unitcost[單價]

      ------szd_productname[產品名稱]

      ccdot_orders{訂單信息表}

      ------szd_orderid[PK]

      ------szd_userid[關聯用戶主鍵]

      ------szd_orderdate[訂單日期]

      ------szd_linkman[聯系人]

      ------szd_email[聯系人email]

      ------szd_phone[聯系電話]

      ------szd_postalcode[送貨處郵編]

      ------szd_address[送貨地址]

      ------szd_result[處理結果]

      ------szd_remark[備注]

      ------szd_songhuoqixian[送貨期限]

      ------szd_songhuofangshi[發貨方式]

      ------szd_fukuanfangshi[付款方式]

      ------szd_error[意外說明]

    posted @ 2008-01-02 15:20 風雨兼程 閱讀(351) | 評論 (0)編輯 收藏

    petshop4.0設計說明asp.net初學者

    petshop4.0設計說明
    一、項目名稱及描述:(實現步驟為:4-3-6-5-2-1)
    1、WEB=表示層
    2、BLL=業務邏輯層
    3、IDAL=數據訪問層接口定義
    4、Model=業務實體
    5、DALFactory=數據層的抽象工廠(創建反射)
    6、SQLServerDAL=SQLServer數據訪問層 / OracleDAL=Oracle數據訪問層

    DBUtility 數據庫訪問組件基礎類

    二、項目引用關系
    1、Web 引用 BLL。
    2、BLL 引用 IDAL,Model,使用DALFactory創建實例。
    3、IDAL 引用 Model。
    4、Model 無引用。
    5、DALFactory 引用IDAL,通過讀取web.config里設置的程序集,加載類的實例,返回給BLL使用。
    6、SQLServerDAL 引用 Model和IDAL,被DALFactory加載的程序集,實現接口里的方法。


    三、實現步驟
    1、創建Model,實現業務實體。
    2、創建IDAL,實現接口。
    3、創建SQLServerDAL,實現接口里的方法。
    4、增加web.config里的配置信息,為SQLServerDAL的程序集。
    5、創建DALFactory,返回程序集的指定類的實例。
    6、創建BLL,調用DALFactory,得到程序集指定類的實例,完成數據操作方法。
    7、創建WEB,調用BLL里的數據操作方法。

    注意:
    1、web.config里的程序集名稱必須與SQLServerDAL里的輸出程序集名稱一致。
    2、DALFactory里只需要一個DataAccess類,可以完成創建所有的程序集實例。
    3、項目創建后,注意修改各項目的默認命名空間和程序集名稱。
    4、注意修改解決方案里的項目依賴。
    5、注意在解決方案里增加各項目引用。

    posted @ 2007-12-26 17:05 風雨兼程 閱讀(1565) | 評論 (0)編輯 收藏

    Getting Real 讀書筆記

    無論是創業還是做項目,無論是單機軟件還是 Web app,都需要遵循的就是滿足需求。

    需求和開發的矛盾,至少在我看來,是產品開發中的主要矛盾。提需求的覺得產品沒有滿足需求,開發的覺得需求不明確或者胡來。最后的結果,要么是產品延期,要么是個破爛。

    是否有一些方法或者經驗,可以指導我們更成功地開發 Web app 呢?或者不僅僅是開發,還包括設計,推廣,人事……作為創業或者實踐的一整套指導?

    這就是我想推薦給大家的《Getting Real》。

    Getting Real 是著名的 37signals 公司(Ruby on Rails 的締造者)去年撰寫的一本書,主要內容是指導小型公司/團體成功地商業運作起 Web 產品,提供了包括相關理念,思路,人員,技術,方法論,實例等等許多信息,非常適合 Web 開發人員,產品人員和創業者參考。

    書專注于以下幾點:
    1. 成功的商業產品,以客戶利益和感受至上。
    2. 小型的團隊,高靈活性和適應性。
    3. 精簡的產品,夠用好用的功能。
    4. 高效的設計和開發過程,杜絕浪費時間,減少需求和開發的矛盾。
    5. 巧妙的推廣和售后支持。
    ……

    posted @ 2007-12-26 15:12 風雨兼程 閱讀(259) | 評論 (0)編輯 收藏

    層隨著鼠標移動

    var c = document.getElementById("divTool");
     c.style.position = "absolute";
     var eT = obj.offsetTop; 
        var eH = obj.offsetHeight+eT; 
     c.style.left = window.event.clientX-event.offsetX+document.documentElement.scrollLeft-20;
        c.style.top = window.event.clientY-event.offsetY+document.documentElement.scrollTop+eH-8;


     c.style.display = "block";

    posted @ 2007-12-26 14:44 風雨兼程 閱讀(563) | 評論 (0)編輯 收藏

    解決downlist 等優先極高于其它控件,浮在其它控件上面

     <iframe style="position:absolute;z-index:9;width:expression(this.nextSibling.offsetWidth);height:expression(this.nextSibling.offsetHeight);top:expression(this.nextSibling.offsetTop);left:expression(this.nextSibling.offsetLeft);" frameborder="0" ></iframe>
      <div id="divTool" onmouseover="javascript:showdiv123()" onmouseout="javascript:HiddivTool()" class="class_title"  style="display:none">
    <table width="100" border="0"  align="center" cellpadding="0" cellspacing="0">
      <tr>
        <td height="20" colspan="2" bgcolor="ffffff" style="width: 100px" >&nbsp;&nbsp;<span class="t1" style="cursor:hand" name="layout/AddPage.aspx" onclick="javascript:openMyPage(this)">More tools</span></td>
      </tr>
      <tr>
        <td height="20" colspan="2"  bgcolor="ffffff"  style="width: 100px">&nbsp;&nbsp;<a href="#">About this tools</a></td>
      </tr><tr>
        <td height="8" colspan="2" bgcolor="ffffff" style="width: 100px"></td>
      </tr>
     
      </table>
    </div>

    posted @ 2007-12-26 14:35 風雨兼程 閱讀(328) | 評論 (0)編輯 收藏

    在PetShop 4.0中ASP.NET緩存的實現

    PetShop作為一個B2C的寵物網上商店,需要充分考慮訪客的用戶體驗,如果因為數據量大而導致Web服務器的響應不及時,頁面和查詢數據遲遲得不到結果,會因此而破壞客戶訪問網站的心情,在耗盡耐心的等待后,可能會失去這一部分客戶。無疑,這是非常糟糕的結果。因而在對其進行體系架構設計時,整個系統的性能就顯得殊為重要。然而,我們不能因噎廢食,因為專注于性能而忽略數據的正確性。在PetShop 3.0版本以及之前的版本,因為ASP.NET緩存的局限性,這一問題并沒有得到很好的解決。PetShop 4.0則引入了SqlCacheDependency特性,使得系統對緩存的處理較之以前大為改觀。

    4.3.1  CacheDependency接口

    PetShop 4.0引入了SqlCacheDependency特性,對Category、Product和Item數據表對應的緩存實施了SQL Cache Invalidation技術。當對應的數據表數據發生更改后,該技術能夠將相關項從緩存中移除。實現這一技術的核心是SqlCacheDependency類,它繼承了CacheDependency類。然而為了保證整個架構的可擴展性,我們也允許設計者建立自定義的CacheDependency類,用以擴展緩存依賴。這就有必要為CacheDependency建立抽象接口,并在web.config文件中進行配置。

    在PetShop 4.0的命名空間PetShop.ICacheDependency中,定義了名為IPetShopCacheDependency接口,它僅包含了一個接口方法:
    public interface IPetShopCacheDependency
    {      
        AggregateCacheDependency GetDependency();
    }

    AggregateCacheDependency是.Net Framework 2.0新增的一個類,它負責監視依賴項對象的集合。當這個集合中的任意一個依賴項對象發生改變時,該依賴項對象對應的緩存對象都將被自動移除。
    AggregateCacheDependency類起到了組合CacheDependency對象的作用,它可以將多個CacheDependency對象甚至于不同類型的CacheDependency對象與緩存項建立關聯。由于PetShop需要為Category、Product和Item數據表建立依賴項,因而IPetShopCacheDependency的接口方法GetDependency()其目的就是返回建立了這些依賴項的AggregateCacheDependency對象。

    4.3.2  CacheDependency實現

    CacheDependency的實現正是為Category、Product和Item數據表建立了對應的SqlCacheDependency類型的依賴項,如代碼所示:
    public abstract class TableDependency : IPetShopCacheDependency
    {
        // This is the separator that's used in web.config
        protected char[] configurationSeparator = new char[] { ',' };

        protected AggregateCacheDependency dependency = new AggregateCacheDependency();
        protected TableDependency(string configKey)
        {
            string dbName = ConfigurationManager.AppSettings["CacheDatabaseName"];
            string tableConfig = ConfigurationManager.AppSettings[configKey];
            string[] tables = tableConfig.Split(configurationSeparator);

            foreach (string tableName in tables)
                dependency.Add(new SqlCacheDependency(dbName, tableName));
        }
        public AggregateCacheDependency GetDependency()
       {
            return dependency;
        }
    }

    需要建立依賴項的數據庫與數據表都配置在web.config文件中,其設置如下:
    <add key="CacheDatabaseName" value="MSPetShop4"/>
    <add key="CategoryTableDependency" value="Category"/>
    <add key="ProductTableDependency" value="Product,Category"/>
    <add key="ItemTableDependency" value="Product,Category,Item"/>

    根據各個數據表間的依賴關系,因而不同的數據表需要建立的依賴項也是不相同的,從配置文件中的value值可以看出。然而不管建立依賴項的多寡,其創建的行為邏輯都是相似的,因而在設計時,抽象了一個共同的類TableDependency,并通過建立帶參數的構造函數,完成對依賴項的建立。由于接口方法GetDependency()的實現中,返回的對象dependency是在受保護的構造函數創建的,因此這里的實現方式也可以看作是Template Method模式的靈活運用。例如TableDependency的子類Product,就是利用父類的構造函數建立了Product、Category數據表的SqlCacheDependency依賴:
    public class Product : TableDependency
    {
        public Product() : base("ProductTableDependency") { }
    }

    如果需要自定義CacheDependency,那么創建依賴項的方式又有不同。然而不管是創建SqlCacheDependency對象,還是自定義的CacheDependency對象,都是將這些依賴項添加到AggregateCacheDependency類中,因而我們也可以為自定義CacheDependency建立專門的類,只要實現IPetShopCacheDependency接口即可。

    4.3.3  CacheDependency工廠

    繼承了抽象類TableDependency的Product、Category和Item類均需要在調用時創建各自的對象。由于它們的父類TableDependency實現了接口IPetShopCacheDependency,因而它們也間接實現了IPetShopCacheDependency接口,這為實現工廠模式提供了前提。

    在PetShop 4.0中,依然利用了配置文件和反射技術來實現工廠模式。命名空間PetShop.CacheDependencyFactory中,類DependencyAccess即為創建IPetShopCacheDependency對象的工廠類:
    public static class DependencyAccess
    {       
        public static IPetShopCacheDependency CreateCategoryDependency()
        {
            return LoadInstance("Category");
        }
        public static IPetShopCacheDependency CreateProductDependency()
        {
            return LoadInstance("Product");
        }
        public static IPetShopCacheDependency CreateItemDependency()
        {
            return LoadInstance("Item");
        }
        private static IPetShopCacheDependency LoadInstance(string className)
        {
            string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];
            string fullyQualifiedClass = path + "." + className;
            return (IPetShopCacheDependency)Assembly.Load(path).CreateInstance(fullyQualifiedClass);
        }
    }
    整個工廠模式的實現如圖4-3所示:

    4-3.gif
     圖4-3 CacheDependency工廠

    雖然DependencyAccess類創建了實現了IPetShopCacheDependency接口的類Category、Product、Item,然而我們之所以引入IPetShopCacheDependency接口,其目的就在于獲得創建了依賴項的AggregateCacheDependency類型的對象。我們可以調用對象的接口方法GetDependency(),如下所示:
    AggregateCacheDependency dependency = DependencyAccess.CreateCategoryDependency().GetDependency();

    為了方便調用者,似乎我們可以對DependencyAccess類進行改進,將原有的CreateCategoryDependency()方法,修改為創建AggregateCacheDependency類型對象的方法。

    然而這樣的做法擾亂了作為工廠類的DependencyAccess的本身職責,且創建IPetShopCacheDependency接口對象的行為仍然有可能被調用者調用,所以保留原有的DependencyAccess類仍然是有必要的。

    在PetShop 4.0的設計中,是通過引入Facade模式以方便調用者更加簡單地獲得AggregateCacheDependency類型對象。

    4.3.4  引入Facade模式

    利用Facade模式可以將一些復雜的邏輯進行包裝,以方便調用者對這些復雜邏輯的調用。就好像提供一個統一的門面一般,將內部的子系統封裝起來,統一為一個高層次的接口。一個典型的Facade模式示意圖如下所示:

    4-4.gif
    圖4-4 Facade模式

    Facade模式的目的并非要引入一個新的功能,而是在現有功能的基礎上提供一個更高層次的抽象,使得調用者可以直接調用,而不用關心內部的實現方式。以CacheDependency工廠為例,我們需要為調用者提供獲得AggregateCacheDependency對象的簡便方法,因而創建了DependencyFacade類:
    public static class DependencyFacade
    {
        private static readonly string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];
        public static AggregateCacheDependency GetCategoryDependency()
        {
            if (!string.IsNullOrEmpty(path))
                return DependencyAccess.CreateCategoryDependency().GetDependency();
            else
                return null;
        }
        public static AggregateCacheDependency GetProductDependency()
        {
            if (!string.IsNullOrEmpty(path))
                return DependencyAccess.CreateProductDependency().GetDependency();
            else
                return null;
            }
        public static AggregateCacheDependency GetItemDependency()
        {
            if (!string.IsNullOrEmpty(path))
                return DependencyAccess.CreateItemDependency().GetDependency();
            else
                return null;
        }
    }

    DependencyFacade類封裝了獲取AggregateCacheDependency類型對象的邏輯,如此一來,調用者可以調用相關方法獲得創建相關依賴項的AggregateCacheDependency類型對象:
    AggregateCacheDependency dependency = DependencyFacade.GetCategoryDependency();

    比起直接調用DependencyAccess類的GetDependency()方法而言,除了方法更簡單之外,同時它還對CacheDependencyAssembly配置節進行了判斷,如果其值為空,則返回null對象。

    在PetShop.Web的App_Code文件夾下,靜態類WebUtility的GetCategoryName()和GetProductName()方法調用了DependencyFacade類。例如GetCategoryName()方法:
    public static string GetCategoryName(string categoryId)
    {
         Category category = new Category();
         if (!enableCaching)
                return category.GetCategory(categoryId).Name;

         string cacheKey = string.Format(CATEGORY_NAME_KEY, categoryId);

         // 檢查緩存中是否存在該數據項;
         string data = (string)HttpRuntime.Cache[cacheKey];
         if (data == null)
         {
               // 通過web.config的配置獲取duration值;
               int cacheDuration = int.Parse(ConfigurationManager.AppSettings["CategoryCacheDuration"]);
               // 如果緩存中不存在該數據項,則通過業務邏輯層訪問數據庫獲取;
               data = category.GetCategory(categoryId).Name;
               // 通過Facade類創建AggregateCacheDependency對象;
               AggregateCacheDependency cd = DependencyFacade.GetCategoryDependency();
               // 將數據項以及AggregateCacheDependency 對象存儲到緩存中;
               HttpRuntime.Cache.Add(cacheKey, data, cd, DateTime.Now.AddHours(cacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
          }
          return data;
    }

    GetCategoryName()方法首先會檢查緩存中是否已經存在CategoryName數據項,如果已經存在,就通過緩存直接獲取數據;否則將通過業務邏輯層調用數據訪問層訪問數據庫獲得CategoryName,在獲得了CategoryName后,會將新獲取的數據連同DependencyFacade類創建的AggregateCacheDependency對象添加到緩存中。

    WebUtility靜態類被表示層的許多頁面所調用,例如Product頁面:
    public partial class Products : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Page.Title = WebUtility.GetCategoryName(Request.QueryString["categoryId"]);
        }
    }

    顯示頁面title的邏輯是放在Page_Load事件方法中,因而每次打開該頁面都要執行獲取CategoryName的方法。如果沒有采用緩存機制,當Category數據較多時,頁面的顯示就會非常緩慢。

    4.3.5  引入Proxy模式

    業務邏輯層BLL中與Product、Category、Item有關的業務方法,其實現邏輯是調用數據訪問層(DAL)對象訪問數據庫,以獲取相關數據。為了改善系統性能,我們就需要為這些實現方法增加緩存機制的邏輯。當我們操作增加了緩存機制的業務對象時,對于調用者而言,應與BLL業務對象的調用保持一致。也即是說,我們需要引入一個新的對象去控制原來的BLL業務對象,這個新的對象就是Proxy模式中的代理對象。

    以PetShop.BLL.Product業務對象為例,PetShop為其建立了代理對象ProductDataProxy,并在GetProductByCategory()等方法中,引入了緩存機制,例如:
    public static class ProductDataProxy
    {

        private static readonly int productTimeout = int.Parse(ConfigurationManager.AppSettings["ProductCacheDuration"]);
        private static readonly bool enableCaching = bool.Parse(ConfigurationManager.AppSettings["EnableCaching"]);
           
        public static IList
    GetProductsByCategory(string category)
        {
            Product product = new Product();

            if (!enableCaching)
                return product.GetProductsByCategory(category);

            string key = "product_by_category_" + category;
            IList data = (IList )HttpRuntime.Cache[key];

            // Check if the data exists in the data cache
            if (data == null)
            {
                data = product.GetProductsByCategory(category);

                // Create a AggregateCacheDependency object from the factory
                AggregateCacheDependency cd = DependencyFacade.GetProductDependency();

                // Store the output in the data cache, and Add the necessary AggregateCacheDependency object
                HttpRuntime.Cache.Add(key, data, cd, DateTime.Now.AddHours(productTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
            }
            return data;
        }
    }

    與業務邏輯層Product對象的GetProductsByCategory()方法相比,增加了緩存機制。當緩存內不存在相關數據項時,則直接調用業務邏輯層Product的GetProductsByCategory()方法來獲取數據,并將其與對應的AggregateCacheDependency對象一起存儲在緩存中。

    引入Proxy模式,實現了在緩存級別上對業務對象的封裝,增強了對業務對象的控制。由于暴露在對象外的方法是一致的,因而對于調用方而言,調用代理對象與真實對象并沒有實質的區別。

    從職責分離與分層設計的角度分析,我更希望這些Proxy對象是被定義在業務邏輯層中,而不像在PetShop的設計那樣,被劃分到表示層UI中。此外,如果需要考慮程序的可擴展性與可替換性,我們還可以為真實對象與代理對象建立統一的接口或抽象類。然而,單以PetShop的表示層調用來看,采用靜態類與靜態方法的方式,或許更為合理。我們需要謹記,“過度設計”是軟件設計的警戒線。

    如果需要對UI層采用緩存機制,將應用程序數據存放到緩存中,就可以調用這些代理對象。以ProductsControl用戶控件為例,調用方式如下:
    productsList.DataSource = ProductDataProxy.GetProductsByCategory(categoryKey);

    productsList對象屬于自定義的CustomList類型,這是一個派生自System.Web.UI.WebControls.DataList控件的類,它的DataSource屬性可以接受IList集合對象。
    不過在PetShop 4.0的設計中,對于類似于ProductsControl類型的控件而言,采用的緩存機制是頁輸出緩存。我們可以從ProductsControl.ascx頁面的Source代碼中發現端倪:
    <%@ OutputCache Duration="100000" VaryByParam="page;categoryId" %>

    與ASP.NET 1.x的頁輸出緩存不同的是,在ASP.NET 2.0中,為ASP.NET用戶控件新引入了CachePolicy屬性,該屬性的類型為ControlCachePolicy類,它以編程方式實現了對ASP.NET用戶控件的輸出緩存設置。我們可以通過設置ControlCachePolicy類的Dependency屬性,來設置與該用戶控件相關的依賴項,例如在ProductsControl用戶控件中,進行如下的設置:
    protected void Page_Load(object sender, EventArgs e)
    {
        this.CachePolicy.Dependency = DependencyFacade.GetProductDependency();
    }

    采用頁輸出緩存,并且利用ControlCachePolicy設置輸出緩存,能夠將業務數據與整個頁面放入到緩存中。這種方式比起應用程序緩存而言,在性能上有很大的提高。同時,它又通過引入的SqlCacheDependency特性有效地避免了“數據過期”的缺點,因而在PetShop 4.0中被廣泛采用。相反,之前為Product、Category、Item業務對象建立的代理對象則被“投閑散置”,僅僅作為一種設計方法的展示而“幸存”與整個系統的源代碼中。

    posted @ 2007-12-26 12:07 風雨兼程 閱讀(1276) | 評論 (1)編輯 收藏

    IList GetCategories();的問題

    petshop4.0中的一段代碼  
       
      public   interface   ICategory   {  
       
      ///   <summary>  
      ///   Method   to   get   all   categories  
      ///   </summary>  
                      ///   <returns>Interface   to   Model   Collection   Generic   of   categories</returns>  
                 
                     
      IList<CategoryInfo>   GetCategories();  
                     
       
                      ///   <summary>  
                      ///   Get   information   on   a   specific   category  
                      ///   </summary>  
                      ///   <param   name="categoryId">Unique   identifier   for   a   category</param>  
                      ///   <returns>Business   Entity   representing   an   category</returns>  
                      CategoryInfo   GetCategory(string   categoryId);  
      }  
       
       
      我知道IList<CategoryInfo>是范型  
      表示list中的item是CategoryInfo對象  
       
       
      請問為什么用IList<CategoryInfo>  
      用List<CategoryInfo>可以嗎?  
       
      兩者有什么區別?謝謝  

    沒有什么區別,這樣寫靈活性大,實現ilist接口的類很多,你寫成list后,也許以后你要改成非list的,就會要改很多代碼
    舉個例子  
       
      RenderControlToString(DataList   L//Control   C)  
       
      你認為是寫control還是寫datalist代碼的通用性高?

      OOP編碼原則:盡可能用接口編程

    posted @ 2007-12-26 11:44 風雨兼程 閱讀(471) | 評論 (0)編輯 收藏

    關于sqlhelper.cs

    public abstract class SqlHelper
              {
                  public static readonly string connectionString = ConfigurationManager.ConnectionStrings["SqlConnString"].ConnectionString;
            
                  SqlConnection conn;

                  #region open SqlConnection
                  public static void Open() {
                       conn = new SqlConnection(connectionString);
                       if (conn.State != ConnectionState.Open)
                          conn.Open();
                  }    
                  #endregion

                  #region close SqlConnection
                  public static void Close() {
                      if (conn != null)
                      {
                          conn.Close();
                          conn.Dispose();
                      }
                  }        
                  #endregion

                  #region prepare SqlCommand
                  private static void PrepareCommand(SqlCommand cmd, CommandType cmdType, string cmdText, SqlParameter[] cmdParms) {
                      Open();
                      cmd.Connection = conn;
                      cmd.CommandType = cmdType;
                      cmd.CommandText = cmdText;

                      if (cmdParms != null)
                      {
                          foreach (SqlParameter parm in cmdParms)
                              cmd.Parameters.Add(parm);
                      }
                  }
                  #endregion

                  #region parm cache
                  /*
                   使用一個哈希表來保存緩存的參數 只緩存參數名
                   哈希表的特點:一個鍵對應一個值key對value(為object需要類型轉化)        不能出現兩個相同的鍵 否則error
             
                   下面的哈希表parmCache定義為static即一次定義全局使用
                   所以可能會出現有人在讀的時候,有人在寫,一般會用Lock就像Asp中用Application["count"]來統計點擊數一樣
                   要先鎖后解鎖
                   但.net框架提供了Synchroized          sync和syncroize中文意思 同步,同時發生
                   來提供這一操作
                  */
                  private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable());

                  public static void CacheParameters(string cacheKey, params SqlParameter[] commandParameters) {
                      parmCache[cacheKey] = commandParameters;
                  }

                  /*
                  1、為何要克隆呢 為何不直接return cachedParms
             
                  有一個參數數組
                  SqlParameter[] parms={
                  new SqlParameter("@num1",SqlDbType.Int,4),
                  new SqlParameter("@num2",SqlDbType.Int,4)
                  }
                  緩存該數組
                  用戶a和b都執行插入操作
                  a用戶插入了1,1
                  b用戶插入了2,2
                  如果不用克隆的話,參數數組只有一份
                  而2個用戶需要根據不同的情況賦于不同的值
                  所以就用了克隆了
            
                  2、(ICloneable)cachedParms[i]先將HashTable轉為ICloneable這樣HashTable就具有了Clone()克隆方法了
                  克隆一份后是什么類型呢,,當然要強制轉化為(SqlParameter)了
                  最后將它賦值給clonedParms[i]
                  */       
                  public static SqlParameter[] GetCachedParameters(string cacheKey) {
                      SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];

                      if (cachedParms == null)
                          return null;
                      SqlParameter[] clonedParms = new SqlParameter[cachedParms.Length];

                      for (int i = 0; i < cachedParms.Length; i++)
                          clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i]).Clone();

                      return clonedParms;
                  }
                  #endregion        
            
                  //below method support sqltext and procedure

                  #region ExecuteReader
                  /*
                   parms的作用,這也是一個知識點
                   舉例:
                   ExecuteReader(*,*,null)成功運行
                   ExecuteReader(*,*,new SqlParameter(*))成功運行
                   ExecuteReader(*,*,new SqlParameter(*),new SqlParameter(*))成功運行
                   ExecuteReader(*,*,{new SqlParameter(*),new SqlParameter(*),})成功運行
                   它讓參數類型和參數個數任意
                   這可給了不是一般的好處,你不必為SqlParameter和SqlParameter[]進行重載,寫上兩個函數
                   又為null寫上一個函數,因為null會不明確調用SqlParameter的函數還是SqlParameter[]的函數
                   啥你不知道我在說什么,打屁屁,那回去看看c++的函數重載
                   */
                  public static SqlDataReader ExecuteReader(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {
                
                      SqlCommand cmd = new SqlCommand();

                      try {
                          PrepareCommand(cmd, null, cmdType, cmdText, commandParameters);
                          SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                          cmd.Parameters.Clear();
                          return rdr;
                      }
                      catch {
                          Close();
                          throw;
                      }
                  }
                  #endregion

                  #region ExecuteNonQuery
                  public static void ExecuteNonQuery(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {

                      SqlCommand cmd = new SqlCommand();

                      PrepareCommand(cmd, cmdType, cmdText, commandParameters);
                      cmd.ExecuteNonQuery();
                      cmd.Parameters.Clear();

                      Close();
                  }
                  #endregion

                  #region ExecuteScalar
                  public static object ExecuteScalar(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {

                      SqlCommand cmd = new SqlCommand();

                      PrepareCommand(cmd, cmdType, cmdText, commandParameters);
                      object val = cmd.ExecuteScalar();
                      cmd.Parameters.Clear();

                      Close();
                      return val;
                  }
                  #endregion


              }
    }

    posted @ 2007-12-26 10:30 風雨兼程 閱讀(904) | 評論 (0)編輯 收藏

    框架怎樣實現高度隨內容自動增高

    main.htm:

    <html> 
        <head> 
           <meta  http-equiv='Content-Type'  content='text/html;  charset=gb2312' /> 
           <meta  name='author'  content='F.R.Huang(meizz梅花雪)//www.meizz.com' /> 
           <title>iframe自適應加載的頁面高度</title> 
        </head> 
        
        <body>
            <div><iframe src="child.htm"></iframe></div>
        </body>
    </html>

    child.htm:

    <html> 
    <head> 
        <meta  http-equiv='Content-Type'  content='text/html;  charset=gb2312' /> 
        <meta  name='author'  content='F.R.Huang(meizz梅花雪)//www.meizz.com' /> 
        <title>iframe  自適應其加載的網頁(多瀏覽器兼容)</title> 
        <script type="text/javascript">
        <!--
        function iframeAutoFit()
        {
            try
            {
                if(window!=parent)
                {
                    var a = parent.document.getElementsByTagName("IFRAME");
                    for(var i=0; i<a.length; i++) //author:meizz
                    {
                        if(a[i].contentWindow==window)
                        {
                            var h1=0, h2=0;
                            a[i].parentNode.style.height = a[i].offsetHeight +"px";
                            a[i].style.height = "10px";
                            if(document.documentElement&&document.documentElement.scrollHeight)
                            {
                                h1=document.documentElement.scrollHeight;
                            }
                            if(document.body) h2=document.body.scrollHeight;

                            var h=Math.max(h1, h2);
                            if(document.all) {h += 4;}
                            if(window.opera) {h += 1;}
                            a[i].style.height = a[i].parentNode.style.height = h +"px";
                        }
                    }
                }
            }
            catch (ex){}
        }
        if(window.attachEvent)
        {
            window.attachEvent("onload",  iframeAutoFit);
            //window.attachEvent("onresize",  iframeAutoFit);
        }
        else if(window.addEventListener)
        {
            window.addEventListener('load',  iframeAutoFit,  false);
            //window.addEventListener('resize',  iframeAutoFit,  false);
        }
        //-->
        </script> 
    </head> 
    <body>
        <table border="1" width="200" style="height: 400px; background-color: yellow">
            <tr>
                <td>iframe  自適應其加載的網頁(多瀏覽器兼容,支持XHTML)</td>
            </tr>
        </table>
    </body> 
    </html>

     很多人反應在IE7里使用它會死機,那是因為在自適應高度時觸發了 window.onresize 事件,而這個事件又去調用這個調整 <iframe> 高度的函數,產生了死循環調用。

    posted @ 2007-04-29 18:03 風雨兼程 閱讀(999) | 評論 (1)編輯 收藏

    怎樣向xml文檔插入HTML標記

    CDATA 區段
           因為網頁中要顯示HTML的源代碼。而在XML中,要實現這樣的功能,就必須使用CDATA標記。在CDATA標記中的信息被解析器原封不動地傳給應用程序,并且不解析該段信息中的任何控制標記。CDATA區域是由:![CDATA[”為開始標記,以“]]為結束標記。例如:例2中的源碼,除了![CDATA[”“]]符號,其余的內容解析器將原封不動地交給下游的應用程序,即使CDATA區域中的開始和結尾的空白以及換行字符等,都同樣會被轉交(注意CDATA是大寫的字符)。 

        如同你在第三章中學到的,你不能直接將(<)或(&)符號放置在元素內容中的字符數據里。要避開這個限制的一種方法是使用字符參照(& #60;或& #38;)或預先定義的普通實體參照(& lt;或& amp;),如同你在第六章中將學到的。然而,如果你需要加入多個(<)或(&)字符,使用這些參照將變得不合適且會讓資料變得難以閱讀。在這種情況下,將包含限制字符的文字放置在CDATA 區段中將會比較容易完成工作。
        CDATA 區段的類型
        CDATA 區段以字符「<![CDATA[」開始,并以「]]>」字符結束。在這兩個定義符號之間,你可以輸入任何字符(包括「<」或「&」),除了「]]>」之外。(因為,該字符會被解釋成CDATA區段的結束。)所有位在CDATA 區段中的字符都被視為元素字符數據的字義 (literal) 部分,而不是XML 標簽。
        下面是一個合法CDATA 區段的范例:
    <![CDATA [
    Here you can type any characters except two right brackets followed
    by a greater-than symbol.
    ]]>
    注意
        關鍵詞CDATA,就像其它你所見到的XML 關鍵詞,必須以大寫字母撰寫。
        如果你想包含一段原始碼或標簽當作被顯示在瀏覽器中元素的真實字符數據的一部份,你可以使用CDATA 區段來防止XML 解析器將「<」或「&」字符解釋成XML 卷標。下面就是一個范例:
    <A-SECTION>
    The following is an example of a very simple HTML page:
    <![CDATA[
    <HTML>
    <HEAD>
    <T99vLE>R.Jones &Sons</T99vLE>
    </HEAD>
    <BODY>
    <P>Welcome to our home page!</P>
    </BODY>
    </HTML>
    ]]>
    </A-SECTION>
        例如,若沒有CDATA 區段,處理器會假設<HTML>是套迭的元素的起始部分,而不是A-SECTION 元素的字符數據的起始部分。
    注意
        既然你可以直接將「<」與「&」字符加入CDATA 區段中,你就不必使用字符參照(& #60;與&)或預先定義的普通實體參照(& lt;與& amp;),筆者將在第六章中解釋字符參照與實體參照。事實上,如果你使用這類的參照,解析器會將參照中的每個字符照字面解釋,且不會更換掉含有「<」或「&」字符的參照。
        你可以放置CDATA 區段的地方
        你可以將CDATA 區段放置在字符數據可以出現的任何地方-也就是說,在元素的內容中卻不在XML 標簽中。下面是一個合法放置CDATA 區段的范例
    <?xml version="1.0"?>
    <MUSICAL>
    <T99vLE_PAGE>

     

    <![CDATA[
    <Oklahoma!>
    By
    Rogers &Hammerstein
    ]]>
    </T99vLE_PAGE>
    <!--Other elements here...-->
    </MUSICAL>
        顯示于下頁的錯誤型式XML 文件包含了兩個違法的CDATA 區段。第一個不是在元素的內容中。第二個則是位在文件元素的內容之中,但卻不是在起始標簽中。
    <?xml version="1.0"?>
    <![CDATA[ ILLEGAL::not within element content!]]>
    <DOC_ELEMENT>
    <SUB_ELEMENT <![CDATA[ ILLEGAL::inside of markup!]]>>
    sub-element content...
    </SUB_ELEMENT>
    </DOC_ELEMENT>
    注意
        CDATA 區段不能成巢狀套迭。亦即,你不能將一個CDATA 區段放到另一個區段中。

    posted @ 2007-04-29 17:42 風雨兼程 閱讀(1848) | 評論 (0)編輯 收藏

    三 生 三 世

    前生,你以緋紅的思念,偎依我的窗前,將一生的愛戀開放成桃花一片。

    ????你深情的佇立在早春三月,以燦爛溫暖我冬季曾經冰封的心河。你將錚錚的誓言,以千枝萬條纏繞在我的窗前,你將依戀深鎖在每一朵花心,呈以幽香親吻我的氣息。

    ????隔窗,是我纖纖的倩影,以一雙翦水的眼眸將你一片迷醉的桃紅粉成癡癡的凝望。在微風細雨里,你致以我呢喃的細語,那雨滴落在花瓣上的顫音是你為我譜寫的相思曲。懵懂的我,總是憑窗而立,期待一襲青衫從幽香裊繞的花樹下,以熱切的眼眸向我走來。紅塵中的我,卻看不穿你糾結滿樹的想我的情結。終究,你在屬于自己季節的尾聲,隔窗,用最后眷戀的眼光,在不舍與哀傷中碎落我的窗下,看著你飄零的身軀,撞入我心扉的是來得深刻而猛烈的疼痛,急促地伸出手,想接住你,在錯過的瞬間,有淚從眼中滴落……。愛,總在失去的瞬間才知道它的存在。含淚,我祈禱來生也盛開成一簇桃花,與你臨風偎依,還你一生的情。?
      
    ????前生,我是桃花一片,以最美的姿色開滿你路過的青石小徑,將一生的眷戀開放成寂寞的等待。等你瀟灑的身影路過時,輕撫我的臉龐,給我一聲愛憐的贊嘆,我以香為魂,伴你在花叢中留戀,聽你為我賦詩,為我吹笛。當你每次轉身離去時,我在微風中心碎的聲音,你是否聽見?總在無你的夜晚獨自浴著冷月的清輝想你,思念便凋落成滿地憔悴的容顏,清晨,花瓣上的露珠便是我為你流了一夜的淚。?

    ???我寂寞而又充滿期待地等著你經過,貪戀地呼吸著有你的空氣,眷戀著你身上發出來的味道,有一種依偎的感覺和莫名的幸福。雖然我不能表達對你的所有的愛戀,只能無語地看著你來去匆忙的身影,你為我的每次駐足和停留,都讓我感動和欣喜萬分,你的憂郁的長嘆總牽動我的心弦,在你看不見里為你暗自落淚。如果可以,我多么希望就這樣在這里靜默地守侯,守侯朝來暮去的時光里有你的身影陪伴,與你偕老。

    ???我只有一季短暫的生命和一顆愛你的心,在不屬于我的季節即將來臨之際,我將離去。雖然我有深深的眷戀和離別的傷痛,可是,生命不容我為你停留。就讓我在季節最后的晨光里,以飛舞的姿勢婆娑而落,在你嗚咽的笛音里慢慢凋零在你的指尖……。我祈禱來生不再為花,許我能語言可以向你傾訴。

    ???今生,我是桃樹下畫花的女子,就著一襲白色長裙,拈一朵桃花簪入發,染幾筆丹青,將你我的姻緣寫進花瓣,等著能解花語的你飄然而來,執我之手,與我傾訴,共我繾綣。

    ???不許愿來世相見,不求一生擁有,只愿今生有緣能與你攜手相擁,走過一段人生。我以三生的情,換你一生的緣,只是不愿再錯過生命中的一段情緣。

    posted @ 2007-02-26 14:05 風雨兼程 閱讀(186) | 評論 (0)編輯 收藏

    一個關于模態彈出窗口刷新父窗體的問題。急

    問:
    我在做一套系統的時候碰到這樣一個問題。
    彈出的模態窗口不能刷新父窗體。例如我新增數據是在模態窗口而添加成功了關閉后父窗體只能手動刷新。這樣就嚴重影響了一些效果。
    我嘗試過一些方法但是始終不對。請各位高手進來一下。

    用OPEN打開的不管是在關閉窗體時自動刷新都沒有任何問題。見下例

    父窗體代碼
    <%@ page contentType="text/html; charset=GBK" %>
    <html>
    <head>
    <title></title>
    </head>
    <body>
    <a href="javascript:void(0)" onclick="window.open('2.html','','')">open</a>
    </body>
    </html>

    子窗體代碼
    <%@ page contentType="text/html; charset=GBK" %>
    <html>
    <head>
    <title></title>
    </head>
    <body onUnload="opener.location.reload()">
    <!-
    用按紐直接刷新父窗體
    <a href="javascript:opener.location.reload()">刷新</a>
    ->
    </body>
    </html>

    ?

    換做模態后的程序。
    父窗體代碼
    <%@ page contentType="text/html; charset=GBK" %><HEAD>
    <body onUnload="opener.location.reload()">
    <script language="JavaScript">
    function showabout()
    {
    ? var returnValue=showModalDialog('2.html','','dialogWidth:520px;dialogHeight:510px;help:no;center:yes;resizable:no;status:no;scroll:no');
    }?
    void(0);
    </script>
    <a href="javascript:void(0)" onClick="showabout()">open</a>

    子窗體代碼
    <%@ page contentType="text/html; charset=GBK" %>
    <html>
    <head>
    <title></title>
    </head>
    <body onUnload="opener.location.reload()">
    <a href="javascript:opener.location.reload()">刷新</a>
    </body>
    </html>

    ?

    請各位參考一下上面的代碼,我感覺錯誤好象是出在
    opener.location.reload()

    謝謝
    ______________________________________________________________________________________________
    答1:
    模態窗口不能在子窗口中直接刷新父窗口

    父窗體代碼
    <%@ page contentType="text/html; charset=GBK" %><HEAD>
    <body onUnload="opener.location.reload()">
    <script language="JavaScript">
    function showabout()
    {
    ? var returnValue=showModalDialog('2.html','','dialogWidth:520px;dialogHeight:510px;help:no;center:yes;resizable:no;status:no;scroll:no');
    ? location.reload()//模態窗口傳值下來后就可以刷新了.
    }?
    void(0);
    </script>
    <a href="javascript:void(0)" onClick="showabout()">open</a>

    子窗體代碼
    <%@ page contentType="text/html; charset=GBK" %>
    <html>
    <head>
    <title></title>
    </head>
    <body onUnload="opener.location.reload()">
    <a href="javascript:opener.location.reload()">刷新</a>//???在子窗口中不能刷新父窗口,只有window.close下去后才可刷新.
    </body>
    </html>

    ______________________________________________________________________________________________
    答2:
    模態對話框是不能用opener引用父窗口的,而是需要父窗口主動傳遞指針變量的
    這個window.showModalDialog有第二個參數,就是做這個用的,你需要把window穿過去,就是這樣
    var returnValue=showModalDialog('2.html',window,'dialogWidth:520px;dialogHeight:510px;help:no;center:yes;resizable:no;status:no;scroll:no');
    這樣在對話框中就可以引用父窗口對象,怎么引用呢,通過window.dialogArgument就可以應用父窗口了。

    ______________________________________________________________________________________________
    答3:
    謝謝。我終于搞定了。
    上面的dialogArgument差個S
    我調了半天。發現在body里面應該加上location
    也就是<body onUnload="window.dialogArguments.location.reload()">

    posted @ 2007-02-09 14:48 風雨兼程 閱讀(5888) | 評論 (4)編輯 收藏

    asp.net中動態變更CSS

    在asp.net中,有的時候要動態變換CSS,比如有的時候做個性化頁面,可以這樣做
    <head>
    <link id="MyStyleSheet" rel="stylesheet" type="text/css" runat="server" />
    </head>
    之后,在要更換CSS的頁面中,使用如下代碼
    Sub Page_Load(Sender As Object, E As EventArgs)
    If Not (IsPostBack)
    MyStyleSheet.Attributes.Add("href","/css/flostyle.css")
    End If
    End Sub??

    posted @ 2007-02-09 13:09 風雨兼程 閱讀(222) | 評論 (0)編輯 收藏

    動態改變Asp.net頁面標題

    1.引用命字空間
    use System.Web.UI.HtmlControls.HtmlGenericControl
    在Asp.net 中你可以使用HtmlGenericControl()來動態改變頁面Title(標題)



    2.為HTML Title標簽設置ID,并將其作為服務器端運行
    <HTML>
    ??<HEAD>
    ????<TITLE ID=MyPageTitle Runat=Server> </TITLE>
    ??</HEAD>
    ?<BODY>
    ??</BODY>
    </HTML>



    3.將Title標設設為Runat=server后,就可以后臺代碼進行訪問~~,通過InnerText或InnerHtml
    來改變其值.
    public class Use_This : System.Web.UI.Page
    ?{
    ??
    Private System.Web.UI.HtmlControls.HtmlGenericControl SetMyTitle;
    ??private void Page_Load(object sender, System.EventArgs e)
    ??{

    ?? SetMyTitle.InnerText = "~哈哈~";

    ??}
    }


    posted @ 2007-02-09 13:08 風雨兼程 閱讀(400) | 評論 (1)編輯 收藏

    怎樣實現動態添加刪除表單中的行

    <script LANGUAGE="JAVASCRIPT">
    var i= 0;
    var a = 0;
    function insertRow(){
     var otr=myTable.insertRow(myTable.rows.length);
     var ocell=otr.insertCell(0);
     ocell.innerHTML="<input type=file name='f1'+a+''>"
     var ocell=otr.insertCell(1);
    ?? ocell.innerHTML="<input type=file name='f2'+a+''>"
    ?? var ocell=otr.insertCell(2);
    ?? ocell.innerHTML="<input type=button name='del'+a+'' value=刪除 onclick=myTable.deleteRow(event.srcElement.parentElement.parentElement.rowIndex)>"
    ?? i++;
    ?? a++;
    }
    </SCRIPT>
    </HEAD>
    <BODY>
    <table id="myTable" border=1 width=600 >
    </table>
    <input type=button onclick="insertRow()"  value="插入行">
    </BODY>

    2
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>添加刪除行</title>
    </head>

    <body><script LANGUAGE="JAVASCRIPT">
    var j= 1;
    var i= 0;
    var a = 0;
    function insertRow(){
     var otr=myTable.insertRow(myTable.rows.length);
     ??? var ocell=otr.insertCell(0);?????????????????????????????????????????
      ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text? size='12' maxlength='7'name='num"+a+"'>"
     ??? var ocell=otr.insertCell(1);
    ?? ocell.innerHTML="<select name='adsl"+a+"'><option value='1'>ADSL</option><option value='2'> LAN</option></select>"
    ????? var ocell=otr.insertCell(2);?????????????????????????????????????????
    ?? ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'value='"+j+"'>"
    ????? var ocell=otr.insertCell(3);?????????????????????????????????????????
    ?? ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"
    ????? var ocell=otr.insertCell(4);?????????????????????????????????????????
    ?? ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"
    ????? var ocell=otr.insertCell(5);?
    ?? ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"?????
    ???? var? ocell=otr.insertCell(6);
    ?? ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=button name='del'+a+'' value=刪除 onclick=myTable.deleteRow(event.srcElement.parentElement.parentElement.rowIndex)>"
    ?? j++;
    ?? i++;
    ?? a++;
    }
    </SCRIPT>
    </HEAD>
    <BODY>
    <table id="myTable"width="778" border="1" align="center" cellspacing="0" bordercolorlight="#66CC33" bordercolordark="ffffff">
    ? <tr>
    ??? <td><div align="center">號碼</div></td>
    ??? <td nowrap><div align="center">寬度類型</div></td>
    ??? <td nowrap><div align="center">起始時間</div></td>
    ??? <td nowrap><div align="center">優惠時間</div></td>
    ??? <td nowrap><div align="center">優惠金額</div></td>
    ??? <td nowrap><div align="center">備注</div></td>
    ??? <td nowrap><div align="center">刪除</div></td>
    ? </tr>
    </table>
    <p align="center">
    ? <input type=button onclick="insertRow()"value="插入行">
    </p>

    <p>&nbsp;</p>
    </BODY>

    </body>
    </html>

    3
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>添加刪除行</title>
    </head>

    <body><script LANGUAGE="JAVASCRIPT">
    var i= 0;
    var a = 0;
    function insertRow(){
     var otr=myTable.insertRow(myTable.rows.length);
     ??? var ocell=otr.insertCell(0);?????????????????????????????????????????
      ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text? size='12' maxlength='7'name='num"+a+"'>"
     ??? var ocell=otr.insertCell(1);
    ?? ocell.innerHTML="<select onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'name='adsl"+a+"'><option value='1'>ADSL</option><option value='2'> LAN</option></select>"
    ????? var ocell=otr.insertCell(2);?????????????????????????????????????????
    ?? ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'value='"+a+"'>"
    ????? var ocell=otr.insertCell(3);?????????????????????????????????????????
    ?? ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"
    ????? var ocell=otr.insertCell(4);?????????????????????????????????????????
    ?? ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"
    ????? var ocell=otr.insertCell(5);?
    ?? ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"?????
    ???? var? ocell=otr.insertCell(6);
    ?? ocell.innerHTML="<input type=button name='del'+a+'' value=刪除 onclick=myTable.deleteRow(event.srcElement.parentElement.parentElement.rowIndex)>"

    ?? i++;
    ?? a++;
    }
    function deleteRow()
    {
    ?? tr=document.getElementById("myTable").rows;
    ?? if(tr.length>1)tr[tr.length-1].removeNode();
    }
    </SCRIPT>
    </HEAD>
    <BODY>
    <table id="myTable"width="778" border="1" align="center" cellspacing="0" bordercolorlight="#66CC33" bordercolordark="ffffff">
    ? <tr>
    ??? <td><div align="center">號碼</div></td>
    ??? <td nowrap><div align="center">寬度類型</div></td>
    ??? <td nowrap><div align="center">起始時間</div></td>
    ??? <td nowrap><div align="center">優惠時間</div></td>
    ??? <td nowrap><div align="center">優惠金額</div></td>
    ??? <td nowrap><div align="center">備注</div></td>
    ??? <td nowrap><div align="center">刪除</div></td>
    ? </tr>
    </table>
    <p align="center">
    ? <input type=button onclick="insertRow()"value="插入行">
    ? <input type=button onclick="deleteRow()"value="刪除行">
    </p>

    <p>&nbsp;</p>
    </BODY>

    </body>
    </html>

    posted @ 2007-01-29 18:58 風雨兼程 閱讀(1217) | 評論 (0)編輯 收藏

    文件上傳

    ?function OutputUpload(id,title) { var tblMain=document.getElementById("Table2"); var tbl=document.getElementById("Table3"); var isExsitfile=document.getElementById("file"+id); var text=document.createTextNode("上傳:"+title+"虛擬形象圖片"); if(isExsitfile==null) { var str= ""; tbl.rows[id].cells[0].insertAdjacentHTML("beforeEnd",str) ; tbl.rows[id].cells[0].appendChild(text); } else { tbl.rows[id].cells[0].removeChild(isExsitfile); tbl.rows[id].cells[0].innerText=""; } }

    if(Request.Form["CHK"]!=null)
    ???{?? string chkvalue=Request.Form["CHK"].ToString();
    ????string[] mylayer=chkvalue.Split(new char[]{','});
    ????string layer="";
    ????for(int i=0;i<mylayer.Length;i++)
    ????{?????
    ?????
    ?????if(layer!="")
    ?????{
    ??????layer+="_";
    ?????}
    ?????layer+=mylayer[i];
    ?????
    ????}
    ????ViewState["layer"]=layer;
    ??????
    ????//得到數據庫編號
    ????if(itemid1.ToString()==null)
    ????{
    ?????itemid1=itemid1+1;
    ????}
    ????else
    ????{
    ?????itemid1=GetItemID()+1;
    ????}
    ????System.Web.HttpFileCollection files=System.Web.HttpContext.Current.Request.Files;
    ????try
    ????{
    ?????for(int i=0;i<files.Count;i++)
    ?????{??
    ??????string fid=itemid1+".gif";
    ??????HttpPostedFile postedFile=files[i];
    ??????
    ??????if(postedFile.FileName.Length>0)
    ??????{
    ???????string fileName,fileExtension;
    ???????fileName=System.IO.Path.GetFileName(postedFile.FileName);
    ???????fileExtension=System.IO.Path.GetExtension(fileName);

    ???????if(fileExtension!=GlobalVars.FILETAILNAME[0])
    ???????{
    ????????Response.Write("<script>alert(\"文件格式不正確?。?!\")</script>");
    ????????return;
    ???????}
    ???????if(i==0)
    ???????{
    ????????//上傳圖片到服務器上??
    ????????BLL.Visual_Items bll=new BLL.Visual_Items();
    ????????bool tf=bll.Exists(this.txtName.Text);
    ????????if(tf==false)
    ????????{??
    ?????????if(System.IO.Directory.Exists(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\0"))
    ?????????{
    ??????????postedFile.SaveAs(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\0\\" + fid);?
    ?????????}
    ?????????else
    ?????????{
    ??????????System.IO.Directory.CreateDirectory(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\0");
    ??????????postedFile.SaveAs(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\0\\" + fid);?
    ?????????}
    ?????????// 把圖片的信息記錄保留到數據庫中
    ?????????string s="images/img_Visual/show/0/"+fid;
    ?????????AddData(s,itemid1,layer);

    ????????}
    ????????else
    ????????{
    ?????????this.Response.Write("<script>alert('數據庫已存在此條數據!')</script>");
    ????????}

    ???????}
    ???????else
    ???????{
    ????????if(System.IO.Directory.Exists(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\"+mylayer[i-1]))
    ????????{
    ?????????postedFile.SaveAs(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\"+mylayer[i-1]+"\\" + fid);
    ????????}
    ????????else
    ????????{
    ?????????System.IO.Directory.CreateDirectory(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\"+mylayer[i-1]);
    ?????????postedFile.SaveAs(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\"+mylayer[i-1]+"\\" + fid);

    ????????}
    ???????}
    ??????}
    ??????else
    ??????{
    ???????Response.Write("<script>alert(\"虛擬形象圖片不能為空!\")</script>");
    ???????return ;

    ??????}
    ?????}?
    ????}
    ????catch(Exception ex)
    ????{
    ?????string sRawURL = Request.RawUrl;

    ?????if(sRawURL.IndexOf("?") > -1)
    ?????{
    ??????sRawURL = sRawURL.Substring(0,sRawURL.IndexOf("?"));
    ?????}????
    ?????
    ?????Response.Write(ex.ToString());
    ????}?
    ???}
    ???else
    ???{
    ?????????????? Response.Write("<script>alert(\"請選擇虛擬形象所屬層??!\")</script>");
    ???}

    posted @ 2006-12-16 11:31 風雨兼程 閱讀(242) | 評論 (0)編輯 收藏

    構建安全的數據訪問

         摘要: 本頁內容http://www.microsoft.com/china/technet/security/guidance/secmod87.mspx 本模塊內容 ...  閱讀全文

    posted @ 2006-11-17 15:08 風雨兼程 閱讀(429) | 評論 (0)編輯 收藏

    DataGrid使用技巧小總結-個性化分頁及復雜表頭

    ? 在使用DataGrid 的時候,總是會有各種各樣的需求,在和數據庫打交道的項目中用的最多的恐怕就屬DataGrid 了吧,微軟有時候做的就差那么一點點,所以就需要我們自己來動手實現啦.

    DataGrid 自定義分頁導航

    無需任何其他第三方控件,在DataGrid 自己分頁的基礎上再個性化一點.
    效果:??

    讓DataGrid自己的分頁實現這樣的效果
    [1][2][3][4][5][6]

    ??

    讓DataGrid自己的分頁實現這樣的效果
    [1][2][3][4][5][6]

    ??

    private void grid_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
    ??{
    ???if(e.Item.ItemType==ListItemType.Pager)
    ???{????
    ????foreach (Control c in e.Item.Cells[0].Controls)
    ????{
    ?????if (c is Label)? //
    當前頁數
    ?????{
    ??????? Label lblpage=(Label)c;
    //??????lblpage.ForeColor= System.Drawing.ColorTranslator.FromHtml("#e78a29");?//#e78a29 ,#FF0000?????
    //??????lblpage.Font.Bold=true;
    ??????? lblpage.Text="[<font color=#e78a29><b>"+lblpage.Text+"</b></font>]";?????
    ??????//((Label)c).ForeColor = System.Drawing.Color.Green;??????
    //??????break;
    ?????}
    ?????if(c is LinkButton) //
    鏈接的其他頁數
    ?????{??????
    ???????? LinkButton linkButton = (LinkButton)c; ??????
    ???????? linkButton.Text = "[" + linkButton.Text+"]";
    ?????}
    ????}????
    ???}
    ??}

    ?

    ?

    DataGrid等控件中的自動編號:

    添加一個模版列:

    <asp:TemplateColumn?HeaderText="No.">
    ????
    <ItemStyle?HorizontalAlign="Center"></ItemStyle>
    ????
    <ItemTemplate>
    ????????
    <asp:Label?runat="server"?Text='<%#?dgCustomize.CurrentPageIndex*dgCustomize.PageSize+dgCustomize.Items.Count+1?%>'>
    ????????
    </asp:Label>
    ????
    </ItemTemplate>
    </asp:TemplateColumn>

    ?

    ?

    DataGrid中創建復雜表頭

    方法一:用table實現

    ??<form id="Form1" method="post" runat="server">
    ???<TABLE id="Table1" runat="server" cellSpacing="1" cellPadding="2" width="580" border="1"
    ????bgcolor="#cc6633" bordercolor="#cc9966" style="FONT-SIZE:9pt;BORDER-BOTTOM:0px">
    ????<TR align="center">
    ?????<TD colspan="2" width="380" style="HEIGHT: 21px"></TD>
    ?????<TD width="200" colspan="2" style="HEIGHT: 21px"></TD>
    ????</TR>
    ????<TR align="center">
    ?????<TD width="200" bgcolor="#66cc99"><FONT face="
    宋體"></FONT></TD>
    ?????<TD width="180" bgcolor="white"><FONT face="
    宋體"></FONT></TD>
    ?????<TD width="160" bgcolor="#99cccc"></TD>
    ?????<TD width="40" bgcolor="#009999"></TD>
    ????</TR>
    ???</TABLE>
    ???<asp:DataGrid id="DataGrid1" width="580px" AlternatingItemStyle-BackColor="#6699ff" CellPadding="2"
    ????CellSpacing="1" BorderWidth="1" BorderColor="#cc9966" Font-Size="9pt" runat="server" ShowHeader="False"
    ????AutoGenerateColumns="False">
    ????<Columns>
    ?????<asp:BoundColumn DataField="Title">
    ??????<ItemStyle Width="200px"></ItemStyle>
    ?????</asp:BoundColumn>
    ?????<asp:BoundColumn DataField="CreateDate">
    ??????<ItemStyle Width="180px"></ItemStyle>
    ?????</asp:BoundColumn>
    ?????<asp:BoundColumn DataField="pid">
    ??????<ItemStyle Width="160px"></ItemStyle>
    ?????</asp:BoundColumn>
    ?????<asp:BoundColumn DataField="HitCount">
    ??????<ItemStyle Width="40px"></ItemStyle>
    ?????</asp:BoundColumn>
    ????</Columns>
    ???</asp:DataGrid>???
    ??</form>?

    窗體頂端

    ?

    ?

    ?

    ?

    ?

    ?

    窗體底端

    方法二:動態生成表頭

    生成雙層表頭:
    ??private void grid_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
    ??{

    ???if (e.Item.ItemType == ListItemType.Header)
    ???{
    //????e.Item.Cells[0].ColumnSpan = 1;//
    這是第一列的跨列數
    ????StringBuilder strtext=new StringBuilder();
    ????strtext.Append("\\</td>");
    ????strtext.Append("<td colspan=4>
    生活照明</td>");
    ????strtext.Append("<td colspan=2>
    一般照明</td>");
    ????strtext.Append("<td colspan=2>
    工付業</td>");
    ????strtext.Append("<td colspan=2>
    農業</td>");
    ????strtext.Append("<td colspan=2>
    合計</td>");
    ????strtext.Append("</tr>");
    ????strtext.Append("<tr>");
    ????strtext.Append("<td>" + e.Item.Cells[0].Text);???????????????
    ????e.Item.Cells[0].Text =strtext.ToString();

    ???}

    }

    整個表頭內容:<tr><td>??e.Item.Cells[0].Text =的內容? </td></tr>

    加起來就是表頭的樣式。

    生活照明

    一般照明

    工付業

    農業

    合計

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    生成三層表頭:

    if (e.Item.ItemType == ListItemType.Header)
    ???{????
    ????StringBuilder strtext=new StringBuilder();
    ????strtext.Append("</td>");
    ????strtext.Append("<td colspan= 6>
    當月</td>");
    ????strtext.Append("</tr>");

    ????strtext.Append("<tr>");?
    ????strtext.Append("<td colspan=2>
    居民</td>");
    ????strtext.Append("<td colspan=2>
    一般</td>");
    ????strtext.Append("<td colspan=2>
    工付業</td>");
    ????strtext.Append("</tr>");

    ????strtext.Append("<tr>");
    ????strtext.Append("<td>" + e.Item.Cells[0].Text);???????????????
    ????e.Item.Cells[0].Text =strtext.ToString();
    ???}

    當月

    居民

    一般

    工付業

    ?

    ?

    ?

    ?

    ?

    ?

    posted @ 2006-11-10 14:31 風雨兼程 閱讀(276) | 評論 (0)編輯 收藏

    Datagrid怎么根據選擇的checkbox編輯和更新多行記錄?

         摘要: 網友問這個問題,寫了一個簡單的例子:前臺:??1<%@?Page?language="c#"?Codebehind="WebForm4.aspx.cs"?AutoEventWireup="false"?Inherits="WebApplication25.WebForm4"?%>??2<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.0?Tran...  閱讀全文

    posted @ 2006-11-10 14:28 風雨兼程 閱讀(389) | 評論 (0)編輯 收藏

    2006年it人士必去的10個網站

    1、chinaunix
    網址:http://www.chinaunix.net/
    簡介:中國最大的linux/unix技術社區。

    2、itpub
    網址:http://www.itpub.net/
    簡介:有名氣的IT技術論壇,看看它的alexa排名就知道有多火了,尤其以數據庫技術討論熱烈而聞名。ITPUB論壇的前身是建立在smiling的oracle小組。

    3、51cto
    網址:http://www.51cto.com/
    簡介:由國內知名IT門戶網站管理團隊,獲近千萬風險投資,于2005年8月正式創立,是國內首家定位于網絡技術人員的綜合性服務平臺,是中國最大的網絡技術網站。

    4、csdn
    網址:http://www.csdn.net/
    簡介:于1999年3月成立,是中國最大的軟件開發人員網站,社區熱心高手眾多,并有不少MVP(微軟最有價值專家)長期活躍在這里,類似懸賞的積分制度,也使論壇增添不少樂趣。

    5、落伍者
    網址:http://www.im286.com/
    簡介:網站站長都應該知道的地方,只是論壇id需要手工審核。

    6、藍色理想
    網址:http://www.blueidea.com/
    簡介:有名的關于網站設計的網站,擁有大量忠實網友。

    7、it寫作社區
    網址:http://www.donews.com/
    簡介:一個可以讓你的思維活躍起來的地方,在這里it評論人和撰稿人可以找到很多的文字素材。

    8、博客堂
    網址:http://blog.joycode.com/
    簡介:眾多MVP交流的地方,這里有各類最新技術,只是網站成員采用邀請制,不提供注冊或者申請功能。

    9、it英雄榜
    網址:http://www.itheroes.cn/
    簡介:網站以介紹it界人士為主,廣大從事it的人員可以從中獲取他們的經驗。

    10、邪惡八進制
    網址:http://www.eviloctal.com/
    簡介:目前為數不多的一個討論氣氛濃厚,技術水平高的網絡安全網站,邪惡八進制信息安全團隊也是一個管理規范、人員素質高的網絡安全小組。

    posted @ 2006-11-08 15:14 風雨兼程 閱讀(235) | 評論 (0)編輯 收藏

    datagrid的正反雙向排序

    呵呵,本沒有寫文章之意,看到好友阿好(hbzxf)的文章,也決定把平時的一些東西寫出來和大家分享!有疏漏之處,敬請大家指教!

    ??? ?在asp.net中利用datagrid控件按列進行排序很是方便??墒俏覀冎荒軉雾椗判?!如果我們需要正反排序那么就需要加入一些代碼控制一下,下面我來詳細講解一下這個過程。

    ? 首先我們需要將datagird控件的屬性設置為 AllowSorting="True",且需要排序列需要制定排序表達式 eg: SortExpression="kmdm"。設置好這些,我們進入代碼文件,來編寫響應排序的事件.

    ? 首先在Page_Load時間中加入如下代碼:

    ???if (!IsPostBack)
    ???{
    ????if(this.kjkm_dg.Attributes["SortExpression"]==null) //這里kjkm_dg為datagrid?? ID
    ????{
    ?????this.kjkm_dg.Attributes["SortExpression"]="kmdm";? //這里給datagrid增加一個排序屬性,且默認排序表達式為kmdm;
    ?????kjkm_dg.Attributes["SortDirection"]="ASC"; //這里給datagrid增加一個排序方向屬性,且默認為升序排列;
    ????}
    ????mikecatbind(); //綁定函數,下面介紹
    ???}

    ??protected void mikecatbind()
    ??{
    ???string sqlStr="select * from zc_kjkm";
    ???DataView dv=new DataView();
    ???
    ???string SortExpression=kjkm_dg.Attributes["SortExpression"];
    ???string SortDirection=kjkm_dg.Attributes["SortDirection"];
    ???dv=us.Bind(sqlStr).Tables[0].DefaultView;? //來自web service的dataset,這里隨便一個ds就可以;
    ???dv.Sort=SortExpression+" "+SortDirection; //指定視圖的排序方式;
    ???kjkm_dg.DataSource=dv; //指定數據源
    ???kjkm_dg.DataBind(); //數據綁定

    }

    ?? 進行完上面的設置后我們進入重要的環節,排序事件的編寫:

    ??private void kjkm_dg_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
    ??{
    ???string SortExpression=e.SortExpression.ToString();? //獲得當前排序表達式
    ???string SortDirection="ASC"; //為排序方向變量賦初值
    ???if(SortExpression==kjkm_dg.Attributes["SortExpression"])? //如果為當前排序列
    ???{
    ????SortDirection=(kjkm_dg.Attributes["SortDirection"].ToString()==SortDirection?"DESC":"ASC");???? //獲得下一次的排序狀態

    ?}
    ???kjkm_dg.Attributes["SortExpression"]=SortExpression;
    ???kjkm_dg.Attributes["SortDirection"]=SortDirection;
    ???mikecatbind();
    ??}

    posted @ 2006-11-08 14:53 風雨兼程 閱讀(207) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: 1000部禁片黄的免费看| 国产成人1024精品免费| 88av免费观看入口在线| 亚洲不卡中文字幕无码| 久久国产精品2020免费m3u8| 日韩亚洲欧洲在线com91tv| 久久成人18免费网站| 国产成人综合亚洲AV第一页| 男女一进一出抽搐免费视频| 亚洲人成网站在线观看播放| 成全高清在线观看免费| 亚洲综合自拍成人| 久久国产精品成人片免费| 亚洲激情视频网站| 成年女人午夜毛片免费视频| AV激情亚洲男人的天堂国语| 国产免费av一区二区三区| 无码 免费 国产在线观看91| 亚洲精品无码专区在线在线播放| 久久成人免费大片| wwwxxx亚洲| 国产大片91精品免费观看男同| 免费人成在线观看播放a| 亚洲日韩欧洲无码av夜夜摸| 99在线在线视频免费视频观看| 亚洲jjzzjjzz在线播放| 吃奶摸下高潮60分钟免费视频| 久久精品无码免费不卡| 亚洲美女免费视频| 国产精品二区三区免费播放心 | 日韩亚洲综合精品国产| 亚洲精品网站在线观看不卡无广告 | WWW免费视频在线观看播放 | 久久久久国产成人精品亚洲午夜| 中国内地毛片免费高清| 亚洲成A∨人片在线观看无码| 在线观看91精品国产不卡免费| a级毛片在线免费| 亚洲一区二区三区高清不卡| 亚洲欧洲精品成人久久曰影片 | 9久9久女女免费精品视频在线观看|