国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 擴展 > MVC > 正文

請求如何進入ASP.NET MVC框架

2024-09-06 20:44:38
字體:
供稿:網(wǎng)友

一、前言

  對于WebForm開發(fā),請求通常是一個以.aspx結(jié)尾的url,對應(yīng)一個物理文件,從代碼的角度來說它其實是一個控件(Page)。而在MVC中,一個請求對應(yīng)的是一個Controller里的Action。熟悉asp.net的朋友都知道,asp.net請求實際都是交給HttpHandler處理(實現(xiàn)了IHttpHandler的類型)。無論是.aspx,.ashx,.asmx 還是MVC里的Action,請求都會交給HttpHandler。具體是在管道事件中,會根據(jù)請求創(chuàng)建一個HttpHandler,并執(zhí)行它的PR方法。對于aspx和ashx都很好理解,因為它們本身就實現(xiàn)了IHttpHandler接口,而MVC的Controller和Action都和HttpHandler沒有關(guān)系,它是如何實現(xiàn)的呢?接下來我們就看一個請求是如何進入mvc框架內(nèi)部的。

二、例子

  WebForm和MVC都是建立在asp.net平臺上的,Webform出現(xiàn)得比較早,那么MVC是如何做到在不影響底層框架,實現(xiàn)擴展的呢?這主要得益于asp.net的路由機制。路由機制并不屬于MVC,WebForm也可以使用它。它的目的是讓一個請求與物理文件分離,原理是通過映射關(guān)系,將請求映射到指定的HttpHandler。例如我們也可以將一個/Admin/User.aspx?name=張三 的請求映射成可讀性更好的/Admin/張三。下面是兩種url的注冊方式:

public static void RegisterRoutes(RouteCollection routes){  //MVC  routes.MapRoute(    name: "Default",    url: "{controller}/{action}/{id}",    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }  );   //WebForm  routes.MapPageRoute(    routeName: "WebForm",    routeUrl: "Admin/{user}",    physicalFile: "~/Admin/User.aspx"  );}

  RouteCollection是一個Route集合,Route封裝了名稱、url模式、約束條件、默認(rèn)值等路由相關(guān)信息。其中,MapPageRoute是RouteCollection定義的方法,而MapRoute是MVC擴展出來的(擴展方法的好處就是可以在不修改原有代碼的情況下添加所需的功能)。它們的目的都是一樣的,創(chuàng)建一個Route對象,添加到集合當(dāng)中;我們也可以new 一個Route對象,然后調(diào)用RouteCollection.Add,效果是一樣的。下面我們主要關(guān)注MVC的實現(xiàn)過程,WebForm其實也是類似的。

三、分析源碼

  接下來我們看MVC是如何利用路由機制實現(xiàn)擴展的。路由機制是通過一個UrlRoutingModule完成的,它是一個實現(xiàn)了IHttpModule的類,路由模塊已經(jīng)默認(rèn)幫我們注冊好了。HttpModule通過注冊HttpApplication事件參與到管道處理請求中,具體是訂閱HttpApplication某個階段的事件。路由機制就是利用這個原理,UrlRoutingModule訂閱了PostResolveRequestCache 事件,實現(xiàn)url的映射。為什么是該事件呢?因為該事件的下一步就要完成請求和物理文件的映射,所以必須要此之前進行攔截。核心代碼如下:

public class UrlRoutingModule : IHttpModule {  public RouteCollection RouteCollection {    get {      if (_routeCollection == null) {        //全局的RouteCollection集合        _routeCollection = RouteTable.Routes;      }      return _routeCollection;    }    set {      _routeCollection = value;    }  }   protected virtual void Init(HttpApplication application) {    //注冊PostResolveRequestCache事件    application.PostResolveRequestCache += OnApplicationPostResolveRequestCache;  }   private void OnApplicationPostResolveRequestCache(object sender, EventArgs e) {    //創(chuàng)建上下文    HttpApplication app = (HttpApplication)sender;    HttpContextBase context = new HttpContextWrapper(app.Context);    PostResolveRequestCache(context);  }   public virtual void PostResolveRequestCache(HttpContextBase context) {    //1.獲取RouteData    RouteData routeData = RouteCollection.GetRouteData(context);    if (routeData == null) {      return;    }    //2.獲取IRouteHandler    IRouteHandler routeHandler = routeData.RouteHandler;    if (routeHandler == null) {           }         //RequestContext保證了HttpContext和RouteData,在后續(xù)使用    RequestContext requestContext = new RequestContext(context, routeData);     context.Request.RequestContext = requestContext;     //3.獲取IHttpHandler    IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);     //重新映射到處理程序    context.RemapHandler(httpHandler);  }}              
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 仙桃市| 新宁县| 龙游县| 西峡县| 德令哈市| 武平县| 阿拉善左旗| 钟山县| 洪洞县| 苍南县| 兴化市| 密云县| 徐汇区| 长寿区| 延川县| 曲阜市| 南平市| 新绛县| 古浪县| 大姚县| 河源市| 齐齐哈尔市| 垦利县| 民和| 成安县| 常宁市| 凤翔县| 新安县| 泽普县| 新河县| 老河口市| 连江县| 溧水县| 台北市| 同德县| 从化市| 平安县| 晋城| 桓台县| 寿光市| 防城港市|