RouteData

RouteData虽然属于Routing组件,但却贯穿mvc的整个流程。不可谓不重要。

先看,RouteData是在何时怎样被使用的。

   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, RoutingResources.UrlRoutingModule_NoRouteHandler, new object[0]));
           }
           if (!(routeHandler is StopRoutingHandler))
           {
               RequestContext requestContext = new RequestContext(context, routeData);
               IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
               if (httpHandler == null)
               {
                   throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoHttpHandler, new object[] { routeHandler.GetType() }));
               }
               context.Items[_requestDataKey] = new RequestData { OriginalPath = context.Request.Path, HttpHandler = httpHandler };
               context.RewritePath("~/UrlRouting.axd");
           }
       }
   }

从这里可以看到,RouteData由RouteCollection.GetRouteData方法从HttpContextBase上下文解析出来。

RouteData里面除了放置RouteHandler以外,还根据Route规则解析url后取得的key-vaule对:比如controller,action之类

然后与HttpContextBase一起封装进RequestContext。交由IHttpHandler(默认是mvcHandler)。

再将httpHandler和Request.Path封装进RequestData放入HttpContextBase里。其构成如下。


下面是从RouteCollection中取得RouteData的方法。可以看出它遍历Collection里的所有Route,返回第一个符合规则RouteData

   1: public RouteData GetRouteData(HttpContextBase httpContext)
   2: {
   3:     if (httpContext == null)
   4:     {
   5:         throw new ArgumentNullException("httpContext");
   6:     }
   7:     if (httpContext.Request == null)
   8:     {
   9:         throw new ArgumentException(RoutingResources.RouteTable_ContextMissingRequest, "httpContext");
  10:     }
  11:     if (!this.RouteExistingFiles)
  12:     {
  13:         string appRelativeCurrentExecutionFilePath = httpContext.Request.AppRelativeCurrentExecutionFilePath;
  14:         if (((appRelativeCurrentExecutionFilePath != "~/") && (this._vpp != null)) && (this._vpp.FileExists(appRelativeCurrentExecutionFilePath) || this._vpp.DirectoryExists(appRelativeCurrentExecutionFilePath)))
  15:         {
  16:             return null;
  17:         }
  18:     }
  19:     using (this.GetReadLock())//线程锁
  20:     {
  21:         foreach (RouteBase base2 in this)//遍历当前集合中的所有RouteBase
  22:         {
  23:             RouteData routeData = base2.GetRouteData(httpContext); //调用RouteBase的RouteData.此处传入的Class是Route.
  24:             if (routeData != null)
  25:             {
  26:                 return routeData;
  27:             }
  28:         }
  29:     }
  30:     return null;
  31: }

这是Route(继承于RouteBase)的GetRouteData实现


084         public override RouteData GetRouteData (HttpContextBase httpContext)
085         {
086             var path = httpContext.Request.AppRelativeCurrentExecutionFilePath;
087             var pathInfo = httpContext.Request.PathInfo;
088  
089             if (!String.IsNullOrEmpty (pathInfo))
090                 throw new NotImplementedException ();
091  
092             // probably code like this causes ArgumentOutOfRangeException under .NET.
093             // It somehow allows such path that is completely equivalent to the Url. Dunno why.
094             if (Url != path && path.Substring (0, 2) != "~/")
095                 return null;
096             path = path.Substring (2);
097  
098             var values = url.Match (path, Defaults);
099             if (values == null)
100                 return null;
101  
102             RouteValueDictionary constraints = Constraints;
103             if (constraints != null)
104                 foreach (var p in constraints)
105                     if (!ProcessConstraint (httpContext, p.Value, p.Key, values, RouteDirection.IncomingRequest))
106                         return null;
107              
108             var rd = new RouteData (this, RouteHandler);
109             RouteValueDictionary rdValues = rd.Values;
110              
111             foreach (var p in values)
112                 rdValues.Add (p.Key, p.Value);
113  
114             RouteValueDictionary dataTokens = DataTokens;
115             if (dataTokens != null) {
116                 RouteValueDictionary rdDataTokens = rd.DataTokens;
117                 foreach (var token in dataTokens)
118                     rdDataTokens.Add (token.Key, token.Value);
119             }
120              
121             return rd;
122         }
123  

关于更具体的代码,可以参照

http://www.cnblogs.com/Wind-Eagle/archive/2008/12/05/1348374.html


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值