一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - asp.net mvc路由篇 如何找到 IHttpHandler方法介紹

asp.net mvc路由篇 如何找到 IHttpHandler方法介紹

2019-10-09 15:02asp.net教程網(wǎng) ASP.NET教程

學(xué)習(xí)是使用asp.net已經(jīng)有很長一段時(shí)間了,現(xiàn)在就來分析一下mvc的整過過程吧。個(gè)人計(jì)劃寫一個(gè)mvc系列的博文,僅從源代碼的角度來分析mvc。在接觸mvc時(shí)我們一定會經(jīng)歷路由,那么路由這東東是怎么搞出來的啊

學(xué)習(xí)是使用asp.net已經(jīng)有很長一段時(shí)間了,現(xiàn)在就來分析一下mvc的整過過程吧。個(gè)人計(jì)劃寫一個(gè)mvc系列的博文,僅從源代碼的角度來分析mvc。在接觸mvc時(shí)我們一定會經(jīng)歷路由,那么路由這東東是怎么搞出來的啊。在我們的web.config中有這么一句: <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 看來路由是它咋負(fù)責(zé)了。在這個(gè)dll中有一個(gè)很特殊的類UrlRoutingModule 
我們來看看它里面主要的核心代碼吧: 

復(fù)制代碼代碼如下:


protected virtual void Init(HttpApplication application) 

if (application.Context.Items[_contextKey] == null) 

application.Context.Items[_contextKey] = _contextKey; 
application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache); 



private void OnApplicationPostResolveRequestCache(object sender, EventArgs e) 

HttpContextBase context = new HttpContextWrapper(((HttpApplication) sender).Context); 
this.PostResolveRequestCache(context); 


public virtual void PostResolveRequestCache(HttpContextBase context) 

RouteData routeData = this.RouteCollection.GetRouteData(context); 
if (routeData != null) 

IRouteHandler routeHandler = routeData.RouteHandler; 
if (routeHandler == null) 

throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("UrlRoutingModule_NoRouteHandler"), new object[0])); 

if (!(routeHandler is StopRoutingHandler)) 

RequestContext requestContext = new RequestContext(context, routeData); 
context.Request.RequestContext = requestContext; 
IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext); 
if (httpHandler == null) 

throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("UrlRoutingModule_NoHttpHandler"), new object[] { routeHandler.GetType() })); 

if (httpHandler is UrlAuthFailureHandler) 

if (!FormsAuthenticationModule.FormsAuthRequired) 

throw new HttpException(0x191, SR.GetString("Assess_Denied_Description3")); 

UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this); 

else 

context.RemapHandler(httpHandler); 




在IHttpModule.Init中注冊了一個(gè)PostResolveRequestCache事件,而該事件主要是調(diào)用PostResolveRequestCache這個(gè)方法,在這個(gè)方法里面有幾句很重要的代碼是 

復(fù)制代碼代碼如下:


RouteData routeData = this.RouteCollection.GetRouteData(context); 
IRouteHandler routeHandler = routeData.RouteHandler; 
RequestContext requestContext = new RequestContext(context, routeData); 
context.Request.RequestContext = requestContext; 
IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext); 
context.RemapHandler(httpHandler); 


讓我們來分析第一句RouteData routeData = this.RouteCollection.GetRouteData(context) ,這句我們猜測是獲取路由信息。要想理解這句代碼又得回到我們程序中來,我們在Global.asax.cs文件中的RegisterRoutes方法中,默認(rèn)有這么一句 

復(fù)制代碼代碼如下:


routes.MapRoute( 
"Default", // 路由名稱 
"{controller}/{action}/{id}", // 帶有參數(shù)的 URL 
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 參數(shù)默認(rèn)值 
); 


這句代碼主要是注冊一個(gè)路由,這里的url要注意不能隨便寫,需要有controller和action。具體是怎么實(shí)現(xiàn)的了? 

復(fù)制代碼代碼如下:


public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) { 
Route route = new Route(url, new MvcRouteHandler()) { 
Defaults = new RouteValueDictionary(defaults), 
Constraints = new RouteValueDictionary(constraints), 
DataTokens = new RouteValueDictionary() 
}; 

if ((namespaces != null) && (namespaces.Length > 0)) { 
route.DataTokens["Namespaces"] = namespaces; 

routes.Add(name, route); 
return route; 


各參數(shù)如下 

復(fù)制代碼代碼如下:


routeName="Default", // 路由名稱 
routeUrl= "{controller}/{action}/{id}", // 帶有參數(shù)的 URL 
defaults=new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 參數(shù)默認(rèn)值 
constraints=null 
namespaces=null 


在這里創(chuàng)建了一個(gè)Route實(shí)例并且把它加入到RouteCollection中了。 
現(xiàn)在又讓我們回到 RouteData routeData = this.RouteCollection.GetRouteData(context);這句代碼中來,GetRouteData的主要代碼如下: 

復(fù)制代碼代碼如下:


public RouteData GetRouteData(HttpContextBase httpContext) 

using (this.GetReadLock()) 

foreach (RouteBase base2 in this) 

RouteData routeData = base2.GetRouteData(httpContext); 
if (routeData != null) 

return routeData; 



return null; 


在這里的base2就是我們先前調(diào)用MapRoute是添加的Route的。而Route的GetRouteData的方法如下: 

復(fù)制代碼代碼如下:


public override RouteData GetRouteData(HttpContextBase httpContext) 

string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo; 
RouteValueDictionary values = this._parsedRoute.Match(virtualPath, this.Defaults); 
if (values == null) 

return null; 

RouteData data = new RouteData(this, this.RouteHandler); 
if (!this.ProcessConstraints(httpContext, values, RouteDirection.IncomingRequest)) 

return null; 

foreach (KeyValuePair<string, object> pair in values) 

data.Values.Add(pair.Key, pair.Value); 

if (this.DataTokens != null) 

foreach (KeyValuePair<string, object> pair2 in this.DataTokens) 

data.DataTokens[pair2.Key] = pair2.Value; 


return data; 


這個(gè)方法很復(fù)雜,有許多驗(yàn)證和檢查,我們主要關(guān)心一句 RouteData data = new RouteData(this, this.RouteHandler); 
當(dāng)然剩下 RequestContext requestContext = new RequestContext(context, routeData); 
context.Request.RequestContext = requestContext;這2句沒什么特別了。 
現(xiàn)在讓我們來看看IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);這句究竟干了些什么,意思很明白獲取Httphandler。 
那么MvcRouteHandler是如何獲取一個(gè)Httphandler的了, 

復(fù)制代碼代碼如下:


protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext) { 
requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext)); 
return new MvcHandler(requestContext); 


直接返回了一個(gè)MvcHandler實(shí)例。 
最有一句context.RemapHandler(httpHandler); 很簡單很好明白吧,在HttpContext的RemapHandler方法中有這么一句 this._remapHandler = handler; 
在HttpContext中有這個(gè)屬性 

復(fù)制代碼代碼如下:


internal IHttpHandler RemapHandlerInstance 

get 

return this._remapHandler; 


那么這個(gè)東西又是什么時(shí)候調(diào)用的了,在HttpApplication的內(nèi)部類MaterializeHandlerExecutionStep中的 void HttpApplication.IExecutionStep.Execute()方法調(diào)用 

復(fù)制代碼代碼如下:


if (httpContext.RemapHandlerInstance != null) 

httpContext.Handler = httpContext.RemapHandlerInstance; 


看到MaterializeHandlerExecutionStep這個(gè)了類名,我想大家都能猜到吧。在內(nèi)部類PipelineStepManager中BuildSteps方法有 

復(fù)制代碼代碼如下:


HttpApplication.IExecutionStep step = new HttpApplication.MaterializeHandlerExecutionStep(app); 
app.AddEventMapping("ManagedPipelineHandler", RequestNotification.MapRequestHandler, false, step); 


我想大家看到這里對mvc整個(gè)路由應(yīng)該有個(gè)大致的理解了吧。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 免费看www| 香蕉久久夜色精品国产小优 | 日本大学jalapsiki | 日本高清免费不卡在线播放 | 日本理论片中文在线观看2828 | 亚洲 欧美 日本 国产 高清 | 四虎在线成人免费网站 | 校花小雪灌满了男人们的浓浆 | 免费视频观看 | 国产剧情麻豆刘玥视频 | 国产精品久久亚洲一区二区 | 美女撒尿部位无遮挡 | 国产高清不卡视频在线播放 | 亚洲日本视频在线 | 亚洲va欧美va天堂v国产综合 | 双性肉文高h | 国产精品理论片在线观看 | 好湿好紧太硬了我好爽 | aaaa黄色片| 能播放的欧美同性videos | 国产久热香蕉在线观看 | 好爽好舒服视频 | 亚洲国产在线播放 | 俄罗斯大逼 | 99在线精品日韩一区免费国产 | 99热精品在线免费观看 | 麻生希在线观看 | 视频一区国产精戏刘婷 | 亚洲精品在看在线观看 | a∨79成人网 | 国产一精品一av一免费爽爽 | 日韩国产欧美精品综合二区 | 国产精品一久久香蕉产线看 | 超级乱淫伦小说1女多男 | 性德国高清xxxxbbbb | 免费观看欧美性一级 | 国产大乳美女挤奶视频 | 日本红怡院亚洲红怡院最新 | 国产精品免费_区二区三区观看 | 狠狠色婷婷 | 国产里番 |