Wind-Eagle

No pain,no gain!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

System.Web.Routing命名空间代码解析(二) Routing类(上)

Posted on 2008-12-05 14:39  Andrew Yin  阅读(1502)  评论(1)    收藏  举报

 

Route类提供了五个属性,并且包装了一个ParsedRoute对象(即已解析过的Route规则),通过察看Route类的构造函数和Url属性的Set方法,我们可以知道的是:Route规则是在添加的时候就解析的,即,在Route类事例化的时候设置Url属性的时候就生成了ParsedRoute对象。

 其他的四个属性分别是 :默认值,约束规则,自带数据,处理Handler.

可以把Router类对比和RouterData类作对比。。。。

Route类的四个方法我将会在 Routing类(下)中介绍。

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Web;

namespace System.Web.Routing
{
    
public enum RouteDirection
    
{
        IncomingRequest,
        UrlGeneration
    }


    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level 
= AspNetHostingPermissionLevel.Minimal),
     AspNetHostingPermission(SecurityAction.LinkDemand, Level 
= AspNetHostingPermissionLevel.Minimal)]
    
public class Route : RouteBase
    
{
        
// Fields
        private ParsedRoute _parsedRoute;
        
private string _url;
        
private const string HttpMethodParameterName = "httpMethod";

        
Constructions

        
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(thisthis.RouteHandler);
            
if (!this.ProcessConstraints(httpContext, values, RouteDirection.IncomingRequest))
                
return null;
            
foreach (KeyValuePair<stringobject> pair in values)
                data.Values.Add(pair.Key, pair.Value);
            
if (this.DataTokens != null)
                
foreach (KeyValuePair<stringobject> pair2 in this.DataTokens)
                    data.DataTokens[pair2.Key] 
= pair2.Value;
            
return data;
        }


        
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        
{
            BoundUrl url 
= this._parsedRoute.Bind(requestContext.RouteData.Values, values, this.Defaults,
                                                  
this.Constraints);
            
if (url == null)
                
return null;
            
if (!this.ProcessConstraints(requestContext.HttpContext, url.Values, RouteDirection.UrlGeneration))
                
return null;
            VirtualPathData data 
= new VirtualPathData(this, url.Url);
            
if (this.DataTokens != null)
                
foreach (KeyValuePair<stringobject> pair in this.DataTokens)
                    data.DataTokens[pair.Key] 
= pair.Value;
            
return data;
        }


        
protected virtual bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName,
                                                 RouteValueDictionary values, RouteDirection routeDirection)
        
{
            
object obj2;
            IRouteConstraint constraint2 
= constraint as IRouteConstraint;
            
if (constraint2 != null)
                
return constraint2.Match(httpContext, this, parameterName, values, routeDirection);
            
string str = constraint as string;
            
if (str == null)
                
throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture,
                                                                  RoutingResources.
                                                                      Route_ValidationMustBeStringOrCustomConstraint,
                                                                  
new object[] {parameterName, this.Url}));
            values.TryGetValue(parameterName, 
out obj2);
            
string input = Convert.ToString(obj2, CultureInfo.InvariantCulture);
            
string pattern = "^(" + str + ")$";
            
return Regex.IsMatch(input, pattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
        }


        
private bool ProcessConstraints(HttpContextBase httpContext, RouteValueDictionary values,
                                        RouteDirection routeDirection)
        
{
            
if (this.Constraints != null)
                
foreach (KeyValuePair<stringobject> pair in this.Constraints)
                    
if (!this.ProcessConstraint(httpContext, pair.Value, pair.Key, values, routeDirection))
                        
return false;
            
return true;
        }


        
// Properties
        public RouteValueDictionary Constraints getset; }

        
public RouteValueDictionary DataTokens getset; }

        
public RouteValueDictionary Defaults getset; }

        
public IRouteHandler RouteHandler getset; }

        
public string Url
        
{
            
get return (this._url ?? string.Empty); }
            
set
            
{
                
this._parsedRoute = RouteParser.Parse(value);
                
this._url = value;
            }

        }

    }

}