Oxite移植到ASP.NET MVC2 BETA 笔记(关于Html.RenderPartialFromSkin)
????? 在將Oxite移植到asp.net mvc2 beta平臺后,經(jīng)過一系列有關(guān)“方法調(diào)用”變更的修正后,終于能夠通過編譯運行起來了!(移植后的源碼參見:http://ecubecms.codeplex.com/)但經(jīng)過測試,發(fā)現(xiàn)存在一個問題:
????? 在site.master中的<%Html.RenderPartialFromSkin("HeadCustomContents"); %>無法加載到"~/skins/admin/Views/…”下的*.ascx了("~/Views/”下的可以),換句話說Oxite中的Htmlhelper擴展方法RenderPartialFromSkin方法無法加載指定皮膚的視圖了。下面對該問題的根源和如何解決做一分析。
一、Oxite 皮膚機制的簡單分析。
1、Oxite首先實現(xiàn)了自己的ViewEngine,即Oxite.Skinning.OxiteWebFormViewEngine。
OxiteWebFormViewEngine繼承自System.Web.MVC.WebFormViewEngine并實現(xiàn)了IOxiteViewEngine接口。它的主要職責是通過設(shè)置RootPath來封裝請求的文件路徑。
2、Oxite自動注冊了一個實現(xiàn)IResultFilter接口的類Oxite.Filters.ViewEnginesResultFilter。ViewEnginesResultFilter的OnResultExecuting方法中根據(jù)指定的皮膚來實例化幾個OxiteWebFormViewEngine(一個皮膚實例化一個,由SkinResolverRegistry.GenerateViewEngines方法來完成的。)并存儲到ResultExecutingContext.Result.ViewEngineCollection和ViewData["OxiteViewEngines"]。
檢索皮膚的優(yōu)先順序:
????? request.QueryString["skin"]
????? request.Cookies["skin"]
????? request.Url.PathAndQuery.StartsWith("/Admin")
????? ViewData["Skin"]??
????? Site.Skin
3、Controller.View和PartialView方法通過ResultExecutingContext.Result.ViewEngineCollection檢索到View(.aspx,.ascx)。而Html.RednerPartial方法則是直接通過ViewEngines.Engines集合來檢索View,結(jié)果是檢索不到有皮膚的View的。所以O(shè)xite定制了RenderPartialFromSkin的Htmlhelper擴展方法,它不通過ViewEngines.Engines而通過ViewData["OxiteViewEngines"](別忘了上面提到過它是由ViewEnginesResultFilter.OnResultExecuting方法存進去的)以檢索到View。
二、為什么加載不到有皮膚的ascx(aspx)文件了?
????? 通過上面的分析,RenderPartialFromSkin方法加載View的原理很清楚了,在ASP.NET MVC1.0中運行的也非常好。但為什么移植到ASP.NET MVC2 BETA就不行了呢?
先看一下Oxite中的RenderPartialFromSkin方法加載到ViewEngines后都干了些什么?
foreach (IViewEngine viewEngine in (IEnumerable<IOxiteViewEngine>)newViewData[viewEngineCollectionName])
{
????????? ViewEngineResult result = viewEngine.FindPartialView(htmlHelper.ViewContext, partialViewName, true);
…
}
上面這段代碼的意思是,從newViewData[viewEngineCollectionName](注:ViewData["OxiteViewEngines”])中檢索每個IViewEngine,并調(diào)用它們的FindPartialView方法。也就是:此處調(diào)用的FindPartialView方法在asp.net mvc2 beta下并沒有找到由該方法的參數(shù)partialViewName指定的View。
三、如何初步解決問題。
????? 先來看一下IViewEngine.FindPartialView方法的定義:
ViewEngineResult IViewEngine.FindPartialView(ControllerContext controllerContext,string partialViewName,bool useCache)
注意一下第三個參數(shù):useCache。RenderPartialFromSkin方法調(diào)用時傳的是true值(意思是使用緩存),那不使用緩存是不是能找到View呢,就把ture改為false。即這樣調(diào)用:ViewEngineResult result = viewEngine.FindPartialView(htmlHelper.ViewContext, partialViewName,false);// true);
竟然成功了!至此,問題已初步解決。但“不使用緩存”,心里總有些遺憾。
四、深入分析問題的根源并完全解決問題。
????? 如何解決上面提到的“遺憾”呢?首先的思路是在OxiteWebFormViewEngine中重載FindPartialView方法,這樣我不但要寫大量代碼,而且要考慮緩存等各種情況,會深陷細節(jié)的泥沼。那只有換另一個思路了,能不能不直接調(diào)用FindPartialView方法。通過反射htmlhelper的RenderPartial方法,發(fā)現(xiàn)它最終是通過調(diào)用ViewEngineCollection.FindPartialView(ControllerContext controllerContext,string partialViewName),這個方法沒有useCache參數(shù),終于見到了解決問題的一絲曙光。
馬上修改Oxite的有關(guān)RenderPartialFromSkin方法源碼。
1、Oxite的ViewEnginesResultFilter中放入ViewData["OxiteViewEngines"]中的是IEnumerable<IOxiteViewEngine>,我把它改為ViewEngineCollection放進去。
IEnumerable<IOxiteViewEngine> viewEngines = skinResolvers.GenerateViewEngines(new SkinResolverContext(requestContext, skin), skin);ViewEngineCollection vec =?new ViewEngineCollection(viewEngines.Cast<IViewEngine>().ToList());
viewData["OxiteViewEngines"] = vec;
注:此處修改的是Oxite.Filters.ViewEnginesResultFilter.setupSkinViewEngines()方法,位于Oxite(項目)/Filters/ViewEnginesResultFilter.cs中。
2、在renderPartialFromSkin方法中改成這樣調(diào)用:
ViewContext vc =?new ViewContext(htmlHelper.ViewContext, htmlHelper.ViewContext.View, newViewData,htmlHelper.ViewContext.TempData);ViewEngineCollection vec = newViewData[viewEngineCollectionName] as ViewEngineCollection;
ViewEngineResult result = vec.FindPartialView(vc, partialViewName);
注:此處修改的是Oxite.Extensions.HtmlHelperExtensions.renderPartialFromSkin()方法,位于Oxite(項目)/Extensions/HtmlHelperExtensions.cs中。
至此,問題終于較完美的解決。
源碼可參考我的ECubeCMS項目:http://ecubecms.codeplex.com/。
轉(zhuǎn)載于:https://www.cnblogs.com/erpcrm/archive/2009/11/26/1611133.html
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Oxite移植到ASP.NET MVC2 BETA 笔记(关于Html.RenderPartialFromSkin)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javascript DOM基础(一)
- 下一篇: 刚学GDI+和.Net WinForm控