如果你在使用asp.net站點,同時又希望它search engine friendly一些,很可能你就希望它有一個sitemaps。在這里我們說的不是asp.net的sitemap,而是sitemaps.org定義的基于xml的sitemaps協(xié)議,注意這兩個名字的大小寫以及單復(fù)數(shù),之后我都會這樣區(qū)分它們。sitemaps協(xié)議有點類似rss或者atom,只不過它描述的不是最近的內(nèi)容更新,而是整個站點的地圖,主要用來描述特定url的重要程度、更新時間及頻率等。搜索引擎如google是支持sitemaps的,通過google webmaster tools(以前叫做google sitemaps)你可以提交你的站點的sitemaps,以便google更好地索引你的網(wǎng)站。
簡單調(diào)用
在asp.net futures (may ctp)之前,如果你想要為你的asp.net站點增加sitemaps支持,恐怕必須自己實現(xiàn)一個特殊的頁面(或者httphandler)用于讀取asp.net sitemap并輸出為sitemaps協(xié)議。而現(xiàn)在這工作可以交給asp.net futures的aspnetsitemapsearchsitemapprovider來做了,你需要做的僅僅是在web.config中寫上幾句。由于這個功能屬于asp.net futures中searchsitemap這個類別,所以需要在web.config中對該節(jié)進行配置:
| 以下為引用的內(nèi)容: <microsoft.web.preview> |
在這個配置里面,我們啟用了searchsitemap,然后配置了一個名為"navigation"的provider,此provider使用aspnetsitemapsearchsitemapprovider類,就這么簡單,和配置任何其他provider的形式完全一致。之后你還需要確保一下有關(guān)的httphandler配置好了,如果你新建網(wǎng)站時使用的模板是asp.net futures的,那么httphandler就應(yīng)該配置好的了,配置信息如下:
| 以下為引用的內(nèi)容: <add verb="*" path="searchsitemaps.axd" type="microsoft.web.preview.search.searchsitemaphandler" validate="true"/> |
這時候,如果你的網(wǎng)站已經(jīng)正常啟用asp.net自身的sitemap功能,例如使用靜態(tài)的web.sitemap,那么訪問searchsitemap.axd就應(yīng)該能看到按照sitemaps協(xié)議輸出的結(jié)果。這時候或許你會很奇怪,為什么結(jié)果只有一條記錄呢?這就是sitemaps的遞歸調(diào)用了,這個主sitemaps僅僅聲名了我們之前配置的那個名為"navigation"的sitemaps的地址,也就是searchsitemaps.axd?sitemap=navigation。打開這個地址,你會發(fā)現(xiàn)仍然是一個sitemaps,它里面包含的就是asp.net sitemap提供的數(shù)據(jù)了。
深入看看
接下來,我們用reflector來看看microsoft.web.preview.search下面的一些類的實現(xiàn)方式。我不準(zhǔn)備詳細分析代碼了,因為代碼都很簡單,直接說說看完的結(jié)果吧。如果你之前瀏覽根據(jù)sitemap生成的sitemaps時發(fā)現(xiàn)少了些東西,在這里你就知道如何把這些項目補充上去了。sitemaps協(xié)議中關(guān)于一個url能夠包括以下幾樣信息:
地址:也就是url本身
最后更新時間
更新頻率:此url的內(nèi)容多久更新一次
重要程度:一個0到1的值,默認值為0.5,搜索引擎并不一定根據(jù)這個值來判斷url的真正重要程度
然而自動生成的sitemaps僅僅包括前兩項信息,如果我們需要后兩項信息就需要手動增加。怎樣手動增加呢?因為sitemapnode類似于字典,能夠訪問this [string key],所以只要sitemapnode[]存在"lastmodified"/"changefrequency"/"priority"這幾個值就能自動輸出到sitemaps中,而且"lastmodified"會覆蓋對應(yīng)page的aspx文件的真實最后更新時間。
簡單舉例說明這功能怎么用,假設(shè)你使用的是靜態(tài)的web.sitemap,我們已經(jīng)習(xí)慣這樣定義一個sitemapnode:
| 以下為引用的內(nèi)容: <sitemapnode url="default.aspx" title="welcome" description="" /> |
而增加特定的屬性只需要這樣定義:
| 以下為引用的內(nèi)容: <sitemapnode url="default.aspx" title="welcome" description="" changefrequency="daily" priority="0.8" /> |
支持dynamic data
上面說了那么多,也就僅僅能做到支持系統(tǒng)自帶的sitemap,而實際上searchsitemap還能夠?qū)ynamic data提供特殊的支持。dynamic data簡單易用,好像ruby on rails那樣支持scaffolding,預(yù)覽了asp.net將來在敏捷方面的發(fā)展。有關(guān)dynamic data control的詳細信息,請參考dflying的文章,我們這里僅討論searchsitemap的支持:
asp.net futures初探——動態(tài)數(shù)據(jù)控件(dynamic data control):入門
asp.net futures初探——動態(tài)數(shù)據(jù)控件(dynamic data control):深入一些
需要支持dynamic data的話,首先你要實現(xiàn)自己的dynamicdatasearchsitemapprovider。大家不要一看到要繼承自系統(tǒng)類實現(xiàn)自己的類就覺得是非常復(fù)雜的事情,其實這里我們僅需要override掉一個函數(shù),也就是dynamicdatasearchsitemapprovider.dataquery()。在這個函數(shù)中,我們需要返回一個ienumerable,其中的元素需要具有主鍵列名屬性以及以下屬性:
| 以下為引用的內(nèi)容: sitemaplastmodified sitemapchangefrequency sitemappriority |
你很可能會問,為什么要是不確定類型的ienumerable而不是確定類型的list<>呢?想想.net framework的什么部分用ienumerable用得最多吧,那就是linq。如果你在querydata()中直接使用linq來篩選數(shù)據(jù),你就不需要創(chuàng)建自定義類型并且自己填充ienumerable了。況且,主鍵列名也不是確定的,如果用一個屬性記錄其名稱用另外一個屬性記錄其值那就很麻煩了,所以asp.net futures選擇了上述充分發(fā)揮linq優(yōu)勢的做法。
最后,我個人感覺searchsitemapproviderbase的設(shè)計有點問題,它作為aspnetsitemapsearchsitemapprovider與dynamicdatasearchsitemapprovider的基類,其中包括querydata()方法,然而此方法只有dynamicdatasearchsitemapprovider用到,很顯然就應(yīng)該將它放置到dynamicdatasearchsitemapprovider里面。
新聞熱點
疑難解答
圖片精選