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

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

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

    ★33°空間‰


                           ----★七彩服飾  【最潮拜☆日單精品】【Esprit】【Hotwind】滿150包郵-女裝-流行女裝    www.7color.hb.cn

                           ----智力比知識重要,素質比智力重要,覺悟比素質更重要
    posts - 110,comments - 35,trackbacks - 0
    ?文章的題目想了好幾個,比如:“在ASP.NET 2.0中開發通配符映射應用程序的一些問題”,后來考慮到為了吸引眼球:),并為了好記,選了這個有點俗的題目。
    ???? 本文主要通過分析在ASP.NET 2.0中開發ASP.NET通配符映射應用程序遇到的一些問題,來說明ASP.NET 2.0中頁面編譯模型的不足之處。文章中如果有不妥之處,歡迎您指出。
    ???? 這里所說的ASP.NET通配符映射應用程序是指在IIS中將所有請求轉發至ASP.NET 2.0運行時處理(對于IIS 5.0,就是建立.*到aspnet_isapi.dll的映射),在程序中通過實現System.Web.IhttpHandlerFactory接口來處理所有請求,實現System.Web.IhttpHandlerFactory的類就相當于一個前端控制器。典型應用就是.Text及基于.Text開發的博客園Blog軟件。
    ???? 在ASP.NET 1.1中,實現通配符映射應用程序大家可能比較清楚,主要是兩點:
    ???? 1、?實現System.Web.IhttpHandlerFactory接口,在GetHandler(HttpContext context, string requestType, string url, string path)中根據請求的url,基于一些規則,找到實際訪問的頁面文件,然后調用PageParser.GetCompiledPageInstance對頁面進行編譯并生成相應的實例處理請求。這樣做的好處是:你可以使用任意的url地址,不必關心是否存在對應的頁面文件,而且可以方便地控制對Web服務器上資源的訪問。
    ???? 2、?在web.config中加上:
    < httpHandlers >
    ????
    < add? path ="*" ?verb ="*" ?type ="Dottext.Common.UrlManager.UrlReWriteHandlerFactory,Dottext.Common" ?validate ="false" ? />

    </ httpHandlers >

    ???? ASP.NET 2.0中新的頁面編譯模型給實現通配符映射應用程序帶來意想不到的問題,下面我以博客園Blog軟件為例與大家一些探討這些問題。
    ???? 在博客園Blog軟件中,實現IhttpHandlerFactory接口的是Dottext.Common.UrlManager. UrlReWriteHandlerFactory,不改變在ASP.NET 1.1中實現的UrlReWriteHandlerFactory代碼,直接在ASP.NET 2.0中編譯并運行,當程序運行在IIS根目錄下,就會在執行PageParser.GetCompiledPageInstance時出現“Object reference not set to an instance of an object”異常(運行在虛擬目錄中不會出現這個問題)。這個問題是ASP.NET 2.0中的一個小Bug,之前我寫的
    PageParser.GetCompiledPageInstance中的一個Bug及解決方法 對這個問題進行了一些分析,這個問題可以通過在PageParser.GetCompiledPageInstance之前調用context.RewritePath("~/default.aspx")解決。
    ????? 接著進行訪問個人Blog主頁的測試,比如:
    http://www.cnblogs.com/dudu ,訪問時出現錯誤:

    “There?is?no?build?provider?registered?for?the?extension?''.?You?can?register?one?in?the? < compilation >< buildProviders > ?section?in?machine.config?or?web.config.?Make?sure?is?has?a?BuildProviderAppliesToAttribute?attribute?which?includes?the?value?'Web'?or?'All'.”

    ???? 在ASP.NET 2.0中,當我們第一次訪問一個頁面時,必不少的兩個過程是:1、頁面編譯 2、創建編譯后的頁面代碼的實例。頁面編譯是根據所訪問的url地址中的擴展名找到匹配的Build Provider對頁面進行編譯。這里出現的問題是由于ASP.NET 2.0運行時沒找到相應的Build Provider,對 http://www.cnblogs.com/dudu 這樣地址,由于使用了通配符映射,在ASP.NET 2.0運行時處理時,得到的擴展名是空(如果沒有使用通配符映射,IIS會自動將地址改為: http://www.cnblogs.com/dudu/default.aspx )。ASP.NET 2.0在這里的設計不足之處是沒有考慮這種情況,無法通過在web.config中進行相應的配置來解決這個問題。如果能提供下面的配置,這個問題就可以輕松解決:

    < buildProviders? >
    ????????
    < add?? extension =".*" ?type ="System.Web.Compilation.PageBuildProvider" />

    </ buildProviders >

    ???? 對于這個問題,我的解決方法是在PageParser.GetCompiledPageInstance之前對url進行處理,在url中加上缺省文件,比如:default.aspx。如果你想使用其他的擴展名,比如:.html,需要在web.config中加上:

    < buildProviders? >
    ????????
    < add?? extension =".html" ?type ="System.Web.Compilation.PageBuildProvider" />

    </ buildProviders >

    ???? 這里還有一個小bug,在上面的錯誤信息“Make sure is has a BuildProvider AppliesToAttribute attribute which includes the value 'Web' or 'All'.”提示需要設置AppliesToAttribute屬性,實際上web.config中并不支持這樣的屬性,可能是正式版之前的ASP.NET 2.0支持過這個屬性,后來去掉后,錯誤提示信息并沒有修改。
    ???? 解決了上面的兩個問題,原以為通配符映射應用程序可以在ASP.NET 2.0中正常運行了,我在本機上測試博客園的程序,頁面能正常訪問。可是今天凌晨在服務器進上將網站升級到ASP.NET 2.0之后,發現ASP.NET運行時在頻繁地編譯頁面,CPU占用一直100%,編譯了一個多小時還在編譯,而且編譯似乎與訪問量有關,訪問少的站點頁面還能打開,博客園主站由于訪問量大,幾乎無法訪問。問題出在哪?于是我從PageParser.GetCompiledPageInstance的源代碼尋找線索,在BuildManager.GetCacheKeyFromVirtualPath中發現可疑之處,BuildManager是根據所請求的虛擬路徑創建緩存鍵,然后根據這個鍵查找或創建頁面編譯后的緩存對象。當對一個頁面發出請求時,BuildManager會檢查緩存,先從內存中檢查,如果內存中沒有就從緩存文件夾(Temporary ASP.NET Files)中查找,如果找到,就直接創建該類型的實例,不進行動態編譯。如果沒找到,就進行頁面編譯工作,而且查找的依據就是根據虛擬路徑創建的緩存鍵。對于通常的頁面訪問方式,這樣處理不會引起問題。但對于通配符映射的情況,就會帶來問題。因為通配符映射時,常見情況是不同的url地址訪問的卻是同一個頁面文件。比如博客園中每篇文章地址不同,但訪問的卻是同樣的頁面代碼,如果按照目前ASP.NET 2.0中的頁面編譯模型,每篇文章第一次訪問都要進行編譯,如果博客園中的幾十萬篇文章被訪問,就要進行幾十萬編譯,難怪今天博客園網站升級至ASP.NET 2.0之后,服務器一直忙于編譯。
    經過測試情況果然這樣,當然訪問地址:
    http://www.cnblogs.com/dudu/archive/2006/03/07/345107.html 時會在Temporary ASP.NET Files中文件夾編譯生成類ASP.dudu_archive_2006_03_07_345107_html,而訪問其他文章地時,也根據文章地址生成另外一個類(2006年3月12日修改:對于這個問題,通過傳給PageParser.GetCompiledPageInstance一個真實的虛擬地址就能解決問題,比如在博客園程序中,對于上面的地址,改為這樣的代碼就行了:GetCompiledPageInstance(app+"~/default.aspx", pagepath, context))。 這樣編譯效率實在太低了!為什么要根據虛擬路徑創建緩鍵,設計者設計時根本沒考慮到通配符映射的問題,真是糟糕的設計!如果按照ASP.NET 1.1那樣根據實際訪問的頁面文件名創建緩存鍵,就可以輕松地避免這個問題。ASP.NET 2.0新的頁面編譯模型在這里似乎是一個敗筆。更糟糕的是連讓開發人員彌補這個Bug的機會都沒有,System.Web.Compilation.BuildManager中沒有提供一個讓開發人員自己設置緩存鍵的方法或屬性。(注:創建緩存鍵的方法是BuildManager. GetCacheKeyFromVirtualPath(VirtualPath virtualPath, out bool keyFromVPP))。更糟糕的是,System.Web.Compilation中的很多類都是internal,很多類的方法是灰色(Reflector用灰色顯示internal static或private,顏色用的不錯,讓人看了就灰心),想自己調用相應方法進行頁面編譯幾乎是不可能(用反射的方法不知能否調用,還沒試過,即使能調用,也要考慮性能上的損失)。難道要自己寫System.Web.Compilation中那些類去處理頁面編譯?我寧愿選擇ASP.NET 1.1,然后等ASP.NET 2.0 SP1,SP1解決不了,等SP2......希望不要等到ASP.NET 3.0。
    ????? 也許你想到了在GetHandler(HttpContext context, string requestType, string url, string path)中調用System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath來編譯并創建頁面的實例。這個方法我也嘗試過,答案是不行,還不如PageParser.GetCompiledPageInstance,至少后者能讓程序運行起來。使用BuildManager.CreateInstanceFromVirtualPath時,當訪問的地址中不帶擴展名時就會出現“The resource cannot be found”錯誤,原因是在GetVPathBuildResultInternal(VirtualPath virtualPath, bool noBuild, bool allowCrossApp, bool allowBuildInPrecompile)中調用了Util.CheckVirtualFileExists(virtualPath)對虛擬路徑進行檢查,檢查時將虛擬路徑轉換為物理路徑,檢查當前請求的頁面文件是否存在,對于通配符映射應用程序,很多地址是實際上不存在的,所以就出現“The resource cannot be found”錯誤。而PageParser.GetCompiledPageInstance中通過調用HostingEnvironment.AddVirtualPathToFileMapping避免了這個問題。而這個方法被
    Internal保護,在代碼中也無法調用。
    ????? 我覺得問題的核心是ASP.NET 2.0設計者在設計時沒有考慮通配符映射這樣的情況。是忽略還是另有考慮,就不得而知了。但ASP.NET 1.1能正確處理這個問題,而ASP.NET 2.0卻處理不了,這里很不應該的。使用通配符映射的Web應用程序用戶只能望ASP.NET 2.0心嘆。最近花了很大精力想把博客園的程序遷移到ASP.NET 2.0,而結果卻是無法遷移到ASP.NET 2.0,令人失望! 只能寄希望微軟推出相應的補丁。
    ???? 還好,使用通配符映射的Web應用程序不是很多,這個問題影響不是很大。

    posted on 2006-09-20 13:36 圣域飛俠 閱讀(206) 評論(0)  編輯  收藏 所屬分類: ASP.NET
    主站蜘蛛池模板: 亚洲人成人网站在线观看| 亚洲一区二区三区免费在线观看| 免费毛片在线播放| 2020久久精品亚洲热综合一本 | 中文字幕无码精品亚洲资源网| 国产亚洲Av综合人人澡精品| 国产无遮挡裸体免费视频 | 四虎影视www四虎免费| 亚洲中文精品久久久久久不卡| 成年在线网站免费观看无广告| 亚洲欧美日韩一区二区三区在线| 嫩草视频在线免费观看| 国产精品亚洲综合天堂夜夜| 无码欧精品亚洲日韩一区夜夜嗨| 一级特黄录像免费播放中文版| 亚洲黄黄黄网站在线观看| 国产福利在线观看永久免费| 亚洲精品国产字幕久久不卡| 日韩精品无码一区二区三区免费 | 亚洲国产欧洲综合997久久| 精品国产免费观看久久久| 无码的免费不卡毛片视频| 亚洲另类激情综合偷自拍图| 0588影视手机免费看片| 亚洲AV无码一区二区三区电影 | 精品一区二区三区无码免费直播 | 精品亚洲成a人在线观看| 亚洲人成网站观看在线播放| 午夜影院免费观看| 亚洲一线产区二线产区区| 亚洲高清无码在线观看| 99在线视频免费| 久久久久久亚洲精品无码| 亚洲午夜久久久久久久久久| 天天影院成人免费观看| 老司机午夜精品视频在线观看免费| 亚洲综合无码AV一区二区| 可以免费看黄视频的网站| 国产成人1024精品免费| 亚洲乱码卡一卡二卡三| 久久亚洲中文字幕精品一区四|