成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

淺析WebFormView中的一個(gè)Bug

開(kāi)發(fā) 開(kāi)發(fā)工具
這里將介紹一個(gè)WebFormView中的Bug,它違反了ASP.NET MVC自身的設(shè)計(jì),希望本文能對(duì)大家有所幫助。

老趙的文章主要是針對(duì)WebFormView中的一個(gè)Bug,這個(gè)Bug在一般情況下不會(huì)出現(xiàn)問(wèn)題,它沒(méi)有遵循ASP.NET MVC既定的模型。

最近需要搞一些重要的功能,結(jié)果又遇到了意料外的障礙。于是又仔細(xì)地看了看ASP.NET和ASP.NET MVC的源代碼,又發(fā)現(xiàn)了以前不曾知道的一些細(xì)節(jié)。您最多說(shuō)ASP.NET WebForms模型不一定適合某些Web應(yīng)用程序的開(kāi)發(fā),但是我想沒(méi)有人可以否認(rèn)ASP.NET中設(shè)計(jì)的巧妙——以及復(fù)雜程度。其實(shí)ASP.NET為我們留下了不少切入點(diǎn),但幾乎沒(méi)什么書(shū)會(huì)提到這些切入點(diǎn),我們只能從微軟自己的框架中一探究竟。

不過(guò)這次我想談的是ASP.NET MVC框架中的一個(gè)Bug,這個(gè)Bug在一般情況下不會(huì)出現(xiàn)問(wèn)題,但是這的確違反了ASP.NET MVC自身的設(shè)計(jì)。這個(gè)問(wèn)題就出在WebFormView對(duì)象的實(shí)現(xiàn)上。

WebFormView是一個(gè)視圖對(duì)象的實(shí)現(xiàn)。而在ASP.NET MVC中,任何視圖都需要實(shí)現(xiàn)一個(gè)IView接口:

  1. public interface IView {  
  2.     void Render(ViewContext viewContext, TextWriter writer);  

Render方法的目的自然是根據(jù)ViewContext對(duì)象中的數(shù)據(jù),將視圖內(nèi)容輸出至TextWriter中。例如在HtmlHelper的RenderPartial方法,便是將一個(gè)Partial View輸出至Response中.

  1. public class HtmlHelper {  
  2.     ...  
  3.     internal virtual void RenderPartialInternal(  
  4.         string partialViewName,  
  5.         ViewDataDictionary viewData,  
  6.         object model,  
  7.         ViewEngineCollection viewEngineCollection) {  
  8.  
  9.         ...  
  10.  
  11.         ViewContext newViewContext = new ViewContext(...);  
  12.         IView view = FindPartialView(newViewContext, partialViewName, viewEngineCollection);  
  13.         view.Render(newViewContext, ViewContext.HttpContext.Response.Output);  
  14.     }  

雖然我認(rèn)為這里的做法是不太妥當(dāng)?shù)模ㄟ@點(diǎn)下次再談),但是這的的確確地表現(xiàn)了Render方法的設(shè)計(jì)意圖。只可惜在WebFormView中,Render方法卻違背了這一設(shè)計(jì):

  1. public class WebFormView : IView {  
  2.     ...  
  3.     public virtual void Render(ViewContext viewContext, TextWriter writer) {  
  4.         ...  
  5.         object viewInstance = ...;  
  6.         ...  
  7.  
  8.         ViewUserControl viewUserControl = viewInstance as ViewUserControl;  
  9.         if (viewUserControl != null) {  
  10.             RenderViewUserControl(viewContext, viewUserControl);  
  11.             return;  
  12.         }  
  13.  
  14.         ...  
  15.     }  
  16.  
  17.     private void RenderViewUserControl(ViewContext context, ViewUserControl control) {  
  18.         ...  
  19.  
  20.         control.ViewData = context.ViewData;  
  21.         control.RenderView(context);  
  22.     }  

對(duì)于Partial View,WebFormView會(huì)加載合適的ViewUserControl實(shí)例,并調(diào)用其RenderView方法生成內(nèi)容……但是,我們的writer參數(shù)到哪里去了?沒(méi)錯(cuò),對(duì)writer參數(shù)Find All Reference就會(huì)發(fā)現(xiàn),這個(gè)參數(shù)根本沒(méi)有用到。既然在這里就已經(jīng)拋棄了我們指定writer,那么接下來(lái)的邏輯再怎么搞也就“那么一回事兒”了。

如果您感興趣閱讀代碼的話(huà),會(huì)發(fā)現(xiàn)事實(shí)上最終這個(gè)對(duì)象被放入了一個(gè)新建的ViewPage對(duì)象中,然后調(diào)用ViewPage的RenderView方法生成視圖內(nèi)容:

  1. public class ViewPage : Page, IViewDataContainer {  
  2.     ...  
  3.     public virtual void RenderView(ViewContext viewContext) {  
  4.         ViewContext = viewContext;  
  5.         InitHelpers();  
  6.         // Tracing requires Page IDs to be unique.  
  7.         ID = Guid.NewGuid().ToString();  
  8.         ProcessRequest(HttpContext.Current);  
  9.     }  

瞧到這個(gè)HttpContext.Current了嗎?也就是說(shuō),無(wú)論RenderView方法何時(shí)調(diào)用,永遠(yuǎn)是向HttpContext.Current輸出內(nèi)容。這個(gè)設(shè)計(jì)很不合理,但是修改起來(lái)還是非常簡(jiǎn)單的,例如以下幾行代碼就可以得到差不多的效果:

  1. public static class HtmlExtensions  
  2. {  
  3.     public static void Partial(this HtmlHelper htmlHelper, string partial)  
  4.     {  
  5.         var viewInstance = BuildManager.CreateInstanceFromVirtualPath(partial, typeof(object));  
  6.         var control = viewInstance as ViewUserControl;  
  7.  
  8.         control.ViewContext = htmlHelper.ViewContext;  
  9.         control.ViewData = htmlHelper.ViewData;  
  10.  
  11.         Page page = new ViewPage();  
  12.         page.Controls.Add(control);  
  13.  
  14.         htmlHelper.ViewContext.HttpContext.Server.Execute(  
  15.             page,  
  16.             htmlHelper.ViewContext.HttpContext.Response.Output,  
  17.             false);  
  18.     }  

但是我不喜歡這種做法,因?yàn)樗鼪](méi)有遵循ASP.NET MVC既定的模型。ASP.NET MVC的確可以擴(kuò)展,但如果需要按照標(biāo)準(zhǔn)擴(kuò)展的話(huà),我們作的事情就多了:

繼承WebFormView,覆蓋RenderView方法。

繼承WebFormViewEngine,覆蓋CreatePartialView方法,返回剛創(chuàng)建的新類(lèi)。

在Application Start時(shí),使用新的ViewEngine類(lèi)替換ASP.NET MVC原有的視圖引擎。

但是在實(shí)際情況中,我會(huì)選擇使用使用第三種方法:下載ASP.NET MVC的源代碼,改寫(xiě),編譯。既然它是MS-PL的授權(quán)協(xié)議,為什么不自己動(dòng)手打一些Patch呢?事實(shí)上,我也打算使用這種方法來(lái)修補(bǔ)ASP.NET MVC的Bug或Design Issue,并發(fā)布一個(gè)臨時(shí)的新項(xiàng)目,就叫作……MvcPatch如何?

原文標(biāo)題:應(yīng)該算是WebFormView的一個(gè)Bug

鏈接:http://www.cnblogs.com/JeffreyZhao/archive/2009/09/14/webviewengine-bug-always-render-to-current-context.html

【編輯推薦】

  1. ASP.NET MVC與WebForm區(qū)別談
  2. 自定義的ControllerFactory:接口實(shí)現(xiàn),支持Area
  3. ASP.NET Routing之“解析URL”功能詳解
  4. 為ASP.NET MVC應(yīng)用添加自定義路由
  5. 學(xué)習(xí)ASP.NET MVC路由的使用方法
責(zé)任編輯:彭凡 來(lái)源: 博客園
相關(guān)推薦

2025-02-13 07:00:00

Dubbo-goJava服務(wù)端

2009-07-14 16:02:42

JDBC例子

2013-06-18 11:37:42

XFSRHEL 6.4

2021-10-08 07:50:57

軟件設(shè)計(jì)程序

2017-10-10 15:14:23

BUGiOS 11蘋(píng)果

2014-12-17 09:40:22

dockerLinuxPaaS

2024-04-22 00:00:01

Redis集群

2015-08-24 10:07:13

程序員bug

2019-08-01 12:59:21

Bug代碼程序

2022-06-15 08:14:40

Go線(xiàn)程遞歸

2023-03-13 08:09:03

Protobuffeature分割

2022-05-16 08:42:26

Pandasbug

2024-08-08 08:09:38

2011-05-19 15:14:49

PostgreSQL

2011-03-03 21:04:08

bug程序員

2018-11-01 13:23:02

網(wǎng)關(guān)APIHTTP

2022-04-06 08:47:03

Dubbo服務(wù)協(xié)議

2021-09-11 19:00:54

Intro元素MemoryCache

2009-08-31 13:53:03

C#創(chuàng)建一個(gè)文件

2017-03-22 09:11:45

bugbug賞金計(jì)劃眾包項(xiàng)目
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久草免费在线视频 | 成人av一区二区在线观看 | 国产a视频| 久久久人成影片一区二区三区 | 国产黄色网址在线观看 | av中文字幕在线 | 日本午夜免费福利视频 | 国产精品视频免费观看 | 精品一区免费 | 免费观看一级特黄欧美大片 | 999免费网站| 中文字幕 国产精品 | 狠狠av| 亚洲精品一级 | 亚洲成人免费av | 中国一级大黄大片 | 色欧美片视频在线观看 | 国产精品国产三级国产aⅴ中文 | 精品永久 | 希岛爱理在线 | 天天爽夜夜操 | 盗摄精品av一区二区三区 | 99国产精品99久久久久久粉嫩 | 精品99久久 | 午夜精品久久久久久不卡欧美一级 | 精品国产一区二区三区久久 | 国产精品a久久久久 | 91精品国产91久久久久久最新 | www操操| 久久999 | 免费在线观看一区二区 | 99精品视频在线观看 | 欧美久久精品一级c片 | 国精品一区二区 | 一区二区免费视频 | 国产精品不卡一区 | 国产蜜臀97一区二区三区 | 亚洲成人激情在线观看 | 欧美久久久久久久久 | 黄色成人亚洲 | 国产欧美一区二区三区久久人妖 |