ASP.NET MVC是如何运行的[2]: URL路由

在一个ASP.NET MVC应用来说,针对HTTP请求的处理和相应定义Controller类型的某个Action方法中,每个HTTP请求的目标对象不再像ASP .NET Web Form应用一样是一个物理文件,而是某个Controller的某个Action。目标Controller和Action的名称包含在HTTP请求中,而ASP.NET MVC的首要任务就是通过当前HTTP请求的解析得到正确的Controller和Action的名称。这个过程是通过ASP.NET MVC的URL路由机制来实现的。

一、RouteData

ASP.NET定义了一个全局的路由表,路由表中的每个路由对象对应着一个将Controller和Action名称作为站位符的URL模板。对于每一个抵达的HTTP请求,ASP.NET MVC会遍历路由表找到一个URL模板的模式与请求地址相匹配的路有对象,并最终解析出以Controller和Action名称为核心的路由数据。在我们自定义的ASP.NET MVC框架中,路由数据通过具有如下定义的RouteData类型表示。

   1: public class RouteData   2: {   3:     public IDictionary<string, object> Values { get; private set; }   4:     public IDictionary<string, object> DataTokens { get; private set; }   5:     public IRouteHandler RouteHandler { get;  set; }   6:     public RouteBase Route { get; set; }   7:    8:     public RouteData()   9:     {  10:         this.Values = new Dictionary<string, object>();  11:         this.DataTokens = new Dictionary<string, object>();  12:         this.DataTokens.Add("namespaces", new List<string>());  13:     }  14:     public string Controller  15:     {  16:         get  17:         {  18:             object controllerName = string.Empty;  19:             this.Values.TryGetValue("controller", out controllerName);  20:             return controllerName.ToString();  21:         }  22:     }  23:     public string ActionName  24:     {  25:         get  26:         {  27:             object actionName = string.Empty;  28:             this.Values.TryGetValue("action", out actionName);  29:             return actionName.ToString();  30:         }  31:     }  32:     public IEnumerable<string> Namespaces  33:     {  34:         get  35:         {  36:             return (IEnumerable<string>)this.DataTokens["namespaces"];  37:         }  38:     }  39: }

从上面的代码片断所示,RouteData定义了两个字典类型的属性Values和DataTokens,前者代表直接从请求地址解析出来的变量,后者代表其他类型的变量。表示Controller和Action名称的同名属性直接从Values字典中提取,对应的Key分别为controller和action。属性Namespaces表示辅助Controller类型的解析而设置的命名空间列表,该属性值从DataTokens字典中提取,对应的Key为namespaces。

我们之前已经提到过ASP.NET MVC本质上是两个自定义的ASP.NET组件来实现的,一个是自定义的HttpModule,另一个是自定义的HttpHandler,而后者从RouteData的RouteHandler属性获得。RouteData的RouteHandler属性类型为IRouteHandler接口,如下面的代码片断所示,该接口具有一个唯一的GetHttpHandler用于返回真正用于处理HTTP请求的HttpHandler对象。

   1: public interface IRouteHandler   2: {   3:     IHttpHandler GetHttpHandler(RequestContext requestContext);   4: }

IRouteHandler接口的GetHttpHandler方法接受一个类型为RequestContext的参数。顾名思义,RequestContext表示当前(HTTP)请求的上下文,其核心就是对当前HttpContext和RouteData的封装,这可以通过如下的代码片断看出来。

   1: public class RequestContext   2: {   3:     public virtual HttpContextBase HttpContext { get; set; }   4:     public virtual RouteData RouteData { get; set; }   5: }

二、Route和RouteTable

RouteData具有一个类型为RouteBase的Route属性,表示当前路由表中与当前请求匹配的路由对象。换句话说,当前的RouteData就是通过该路由对象针对当前HTTP请求进行解析获得的。RouteBase是一个抽象类,如下面的代码片断所示,它仅仅包含一个GetRouteData方法,该方法通过对以HttpContextBase对象表示的当前HTTP上下文进行解析从而获取一个RouteData对象。

   1: public abstract class RouteBase   2: {   3:     public abstract RouteData GetRouteData(HttpContextBase httpContext);   4: }

ASP.NET MVC提供的基于URL模板的路由机制是通过具有如下定义的Route类型实现的。Route是RouteBase的子类,字符串类型的Url属性代表定义的URL模板 。在实现的GetRouteData方法中,通过HttpContextBase获取相对请求地址,如果该地址与定义在模板中的URL模式相匹配则创建一个RouteData返回;否则返回Null。对于返回的RouteData对象,其Values属性表示的字典包含直接通过地址解析出来的变量,而对于DataTokens字典和RouteHandler属性,则直接取自Route对象的同名属性。

   1: public class Route : RouteBase   2: {   3:     public IRouteHandler RouteHandler { get; set; }   4:     public Route()   5:     {   6:         this.DataTokens = new Dictionary<string, object>();   7:         this.RouteHandler = new MvcRouteHandler();   8:     }   9:     public override RouteData GetRouteData(HttpContextBase httpContext)  10:     {  11:         IDictionary<string, object> variables;  12:         if (this.Match(httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2), out variables))  13:         {  14:             RouteData routeData = new RouteData();  15:             foreach (var item in variables)  16:             {  17:                 routeData.Values.Add(item.Key, item.Value);  18:             }  19:             foreach (var item in DataTokens)  20:             {  21:                 routeData.DataTokens.Add(item.Key, item.Value);  22:             }  23:             routeData.RouteHandler = this.RouteHandler;  24:             return routeData;  25:         }  26:         return null;  27:     }  28:     public string Url { get; set; }  29:     public IDictionary<string, object> DataTokens { get; set; }  30:     protected bool Match(string requestUrl, out IDictionary<string,object> variables)  31:     {  32:         variables = new Dictionary<string,object>();  33:         string[] strArray1 = requestUrl.Split('/');  34:         string[] strArray2 = this.Url.Split('/');  35:         if (strArray1.Length != strArray2.Length)  36:         {  37:             return false;  38:         }  39:   40:         for (int i = 0; i < strArray2.Length; i++)  41:         {  42:             if(strArray2[i].StartsWith("{") && strArray2[i].EndsWith("}"))  43:             {  44:                 variables.Add(strArray2[i].Trim("{}".ToCharArray()),strArray1[i]);  45:             }  46:         }  47:         return true;  48:     }  49: }

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索对象
, controller
, 路由
, 属性
, public
一个
,以便于您获取更多的相关知识。

时间: 2024-09-11 22:09:08

ASP.NET MVC是如何运行的[2]: URL路由的相关文章

在ASP.NET MVC中使用IIS级别的URL Rewrite

原文 在ASP.NET MVC中使用IIS级别的URL Rewrite 大约一年半前,我在博客上写过一系列关于URL Rewrite的文章(2.3.4),把ASP.NET平台上进行URL Rewrit的方式和各自地特点进行了较为详细的描述.应该来说,已经讲的非常具体,可以应对90%的情况.其实IIS Rewrite的原理非常容易理解,进行一些简单的变化和推断之后,便可以得出一些问题的原因和解决方案.现在我们就来看一个真实案例:在ASP.NET MVC中使用IIS级别的URL Rewrite. 在

ASP.NET MVC是如何运行的[1]: 建立在“伪”MVC框架上的Web应用

ASP.NET由于采用了管道式设计,具有很好的扩展性,而整个ASP.NET MVC应用框架就是通过扩展ASP.NET实现的.通过上面对ASP.NET管道设计的介绍,我们知道ASP.NET的扩展点只要体现在HttpMoudle和HttpHandler这两个核心组建之上,实际上整个ASP.NET MVC框架就是通过自定义的HttpMoudle(UrlRoutingModule)和HttpHandler(MvcHandler)实现的.为了上读者从整体上把握ASP.NET MVC的工作机制,接下来我按照

ASP.NET MVC是如何运行的(4): Action的执行

作为Controller基类ControllerBase的Execute方法的核心在于对Action方法的执行和作为方法返回的ActionResult的执行,两者的执行是通过一个叫做ActionInvoker的组件来完成的. 一.ActionInvoker 我们同样为ActionInvoker定义了一个接口IActionInvoker.如下面的代码片断所示,该接口定义了一个唯一的方法InvokeAction用于执行指定名称的Action方法,该方法的第一个参数是一个表示基于当前Controlle

ASP.NET MVC是如何运行的(3): Controller的激活

ASP.NET MVC的URL路由系统通过注册的路由表对HTTP请求进行解析从而得到一个用于封装路由数据的RouteData对象,而这个过程是通过自定义的UrlRoutingModule对HttpApplication的PostResolveRequestCache事件进行注册实现的.RouteData中已经包含了目标Controller的名称,现在我们来进一步分析真正的Controller对象是如何被激活的.我们首先需要了解一个类型为MvcRouteHandler的类型. 一.MvcRoute

通过一个模拟程序让你明白ASP.NET MVC是如何运行的

ASP.NET MVC的路由系统通过对HTTP请求的解析得到表示Controller.Action和其他相关的数据,并以此为依据激活Controller对象,调用相应的Action方法,并将方法返回的ActionResult写入HTTP回复中.为了更好的演示其实现原理,我创建一个简单的ASP.NET Web应用来模拟ASP.NET MVC的路由机制.这个例子中的相关组件基本上就是根据ASP.NET MVC的同名组件设计的,只是我将它们进行了最大限度的简化,因为我们只需要用它来演示大致的实现原理而

在ASP.NET MVC中使用带后缀的URL

在 ASP.NET WebForm中不少人做过通过Url重写使Url中不带后缀,这次我们做的正好相反.假设我们需要将URL后缀设置成shtml,以新建ASP.NET MVC项目时默认的项目为例.如果要访问登陆页,则URL为http://localhost/Account/Login,Account匹配Account Controller,Login匹配Login Action.如果我们要将URL改为http://localhost/Account/Login.shtml,在不改变Route的情况

asp.net MVC中怎么获取上传图片的URL

问题描述 如图,我要对view里面上传图片加个文字水印,然后上传到服务器上面, 解决方案 解决方案二: 解决方案三:能得到文件的名称吗?还有,你要上传文件的路径干嘛?难道服务器还能去远程读取你本地机器的地址吗?解决方案四:引用2楼az6161311的回复: 能得到文件的名称吗?还有,你要上传文件的路径干嘛?难道服务器还能去远程读取你本地机器的地址吗? 不是要路径才能操作这个图片么,给他加文字上去解决方案五:引用3楼qq_22326361的回复: Quote: 引用2楼az6161311的回复:

ASP.NET MVC的运行机制

一.ASP.NET + MVC IIS与ASP.NET管道 MVC.MVP以及Model2[上篇] MVC.MVP以及Model2[下篇] ASP.NET MVC是如何运行的[1]: 建立在"伪"MVC框架上的Web应用 ASP.NET MVC是如何运行的[2]: URL路由 ASP.NET MVC是如何运行的[3]: Controller的激活 ASP.NET MVC是如何运行的[4]: Action的执行 二.URL 路由 ASP.NET的路由系统:URL与物理文件的分离 ASP.

How ASP.NET MVC Works?

一.ASP.NET + MVC IIS与ASP.NET管道 MVC.MVP以及Model2[上篇] MVC.MVP以及Model2[下篇] ASP.NET MVC是如何运行的[1]: 建立在"伪"MVC框架上的Web应用 ASP.NET MVC是如何运行的[2]: URL路由 ASP.NET MVC是如何运行的[3]: Controller的激活 ASP.NET MVC是如何运行的[4]: Action的执行 二.URL 路由 ASP.NET的路由系统:URL与物理文件的分离 ASP.