请求一个MVC页面的处理过程
1.浏览器发送一个Home/Index 的链接请求到iis。iis发现时一个asp.net处理程序。则调用asp.net_isapi 扩展程序发送asp.net框架
2.在asp.net的第七个管道事件中会遍历UrlRoutingModule中RouteCollection的RoteBase集合 通过调用其GetRouteData方法进行路由匹配返回一个实现了IRoteHandler的类的对象,没有则返回null继续向下遍历
3.调用IRoteHandler的getIhttpHanderl获得实现了IhttpHandler的类的对象。再在11 到12个事件管道调用其ProcessRequset 执行处理逻辑将结果写入response
这里我们会发现很多个扩展点 1.自定义RoteBase 写入集合 2.自定义IroteHandler 3.自定义IhttpHandler
尝试自定一个RoteBase 并添加到UrlRoutingModule的RoteBase集合中
public class MyRote : RouteBase{/// <summary>/// 此方法是处理请求是否跟当前路由匹配/// </summary>/// <param name="httpContext"></param>/// <returns></returns>public override RouteData GetRouteData(HttpContextBase httpContext){//假如我们定义 如果是谷歌用户则命中路由当前路由if (httpContext.Request.UserAgent.IndexOf("Chrome") >= 0){RouteData rd= new RouteData(this, new MvcRouteHandler());//假设命中了此路由 解析获得请求控制器为Home action方法为Indexrd.Values.Add("controller", "Home");rd.Values.Add("action", "MyRoteIndex");return rd;}return null;}/// <summary>/// 此方法 在通过Url.action()的时候根据当前路由生成路径/// </summary>/// <param name="requestContext"></param>/// <param name="values"></param>/// <returns></returns>public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values){return new VirtualPathData(this,"Home/MyRoteIndex");}}
在RouteConfig添加到UrlRoutingModule 的RouteCollection中
public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");/**** 因为路由匹配是遍历匹配的 所以我们写到第一个位置。否则可能会出现匹配到下面的路由 *添加到RoteBase集合。下面的方法是个扩展方法内部也是调用的add方法***/routes.Add("myRote", new MyRote.MyRote());routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}
这个时候我们用谷歌就会发现无论我们请求哪个页面 都是调用Home/MyRoteIndex 还有在视图页面通过@url.acton 通过路由生成链接也是都是Home/MyRoteIndex
2.自己实现自己的RoteHandler 和IhttpHandler
public class MyRoteHandler :IRouteHandler{public IHttpHandler GetHttpHandler(RequestContext requestContext){//返回我们自己的IttpHandler处理对象return new MyIHttpHandler();}}public class MyIHttpHandler : IHttpHandler{public bool IsReusable{get { return true; }}/**** 我们之前说了 在第11到12个事件管道是调用这个方法写入response * MVC实现的IhttpHandler则是通过匹配的路由 反射调用指定控制器的action方法 再调用ActionrResult的ExcuteReuslt方法将结果写入response* asp.net处理页面则是调用后台页类的ProcessRequset方法处理我们程序员写的逻辑了***/public void ProcessRequest(HttpContext context){if (context.Request.UserAgent.IndexOf("Chrome") >= 0){context.Response.Write("当前是谷歌浏览器");}else if (context.Request.UserAgent.IndexOf("MSIE") >= 0){context.Response.Write("当前是Ie浏览器");}else{context.Response.Write("其他浏览器");}}}
/// <summary>/// 此方法是处理请求是否跟当前路由匹配/// </summary>/// <param name="httpContext"></param>/// <returns></returns>public override RouteData GetRouteData(HttpContextBase httpContext){//方便调试则默认他是全部请求匹配此路由if (true){//这里的RoteHandler则返回我们自己的实现RouteData rd= new RouteData(this, new MyRoteHandler());//假设命中了此路由 解析获得请求控制器为Home action方法为Indexrd.Values.Add("controller", "Home");rd.Values.Add("action", "MyRoteIndex");return rd;}}/// <summary>/// 此方法 在通过Url.action()的时候根据当前路由生成路径/// </summary>/// <param name="requestContext"></param>/// <param name="values"></param>/// <returns></returns>public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values){return new VirtualPathData(this,"Home/MyRoteIndex");}
因为都是匹配我们的自己实现的路由 和返回我们自己的RoteHandelr 最终结果是请求任何url都是执行我们自己的IttpHanler的处理逻辑的方法