玩转 Route

Handler类:
DefaultRouteHandler
 1  public class DefaultRouteHandler:IRouteHandler
 2     {
 3       
 4         IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
 5         {
 6             if (requestContext == null)
 7                 throw new ArgumentNullException("requestContext");                
 8             RouteData rd=requestContext.RouteData;
 9             var dr=rd.Route as CustomRoute;
10             if (dr == null)
11                 throw new ArgumentException("The argument RequestContext does not have DynamicDataRoute");
12             string viewName=dr.GetFieldFromRouteData(rd, "ViewName");
13             string category=dr.GetFieldFromRouteData(rd, "Category");
14             if (string.IsNullOrEmpty(viewName))              
15                 throw new ArgumentNullException("ViewName");
16             if (string.IsNullOrEmpty(category))
17                 throw new ArgumentNullException("Category");
18             return HandlerHelper.CreateHandler(category,viewName); 
19         }
20 
21         public RequestContext GetRequestContext(HttpContext httpContext, RouteData routedata)
22         {
23             return new RequestContext(new HttpContextWrapper(httpContext), routedata);
24         }
25 
26         public RequestContext GetRequestContext(HttpContext httpContext)
27         {
28             return GetRequestContext(httpContext, new RouteData());
29         }
30        
31     }
PreRouteHandler
 1 public  class PreRouteHandler : IRouteHandler
 2     {
 3        IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
 4        {
 5            if (requestContext == null)
 6                throw new ArgumentNullException("requestContext");
 7            RouteData rd=requestContext.RouteData;
 8            var dr=rd.Route as CustomRoute;
 9            if (dr == null)
10                throw new ArgumentException("The argument RequestContext does not have DynamicDataRoute");
11            string viewName=dr.GetFieldFromRouteData(rd, "ViewName");
12            string category=dr.GetFieldFromRouteData(rd, "Category");
13            string pre=dr.GetFieldFromRouteData(rd, "Pre");
14            if (string.IsNullOrEmpty(viewName))
15                throw new ArgumentNullException("ViewName");
16            if (string.IsNullOrEmpty(category))
17                throw new ArgumentNullException("Category");
18            if (string.IsNullOrEmpty(pre))
19               throw new ArgumentNullException("Pre");
20            return HandlerHelper.CreateHandler(category, viewName, pre);
21        }
22     }
HandlerHelper
 1 //由相关参数 引用虚拟目录中的文件文件  进行响应
 2    public class HandlerHelper
 3     {
 4         const string BaseFolderVirtualPath="~/HandlerFolder/";
 5        
 6         public static IHttpHandler CreateHandler(string path)
 7         {
 8             IHttpHandler ret = null;
 9             VirtualPathProvider vpp = HostingEnvironment.VirtualPathProvider;
10             if (vpp != null && vpp.FileExists(path))
11                 ret = BuildManager.CreateInstanceFromVirtualPath(path, typeof(Page)) as IHttpHandler;
12             return ret;
13         }
14 
15         public static IHttpHandler CreateHandler(string Category, string ViewName)
16         {
17             string path=BaseFolderVirtualPath+Category+"/"+ViewName+".aspx";
18             return CreateHandler(path);
19         }
20         public static IHttpHandler CreateHandler(string Category, string ViewName,string Pre)
21         {
22             string path=BaseFolderVirtualPath+Category+"/"+Pre+"-"+ViewName+".aspx";
23             return CreateHandler(path);
24         }
25     }

 Route路由类:

CustomRoute
 1  //获取路由之中 传递的 变量信息
 2     public class CustomRoute: Route
 3     {
 4         public CustomRoute(string url)
 5             : base(url, null)
 6         {
 7             RouteHandler=new DefaultRouteHandler();
 8         }
 9 
10         public CustomRoute(string url, IRouteHandler handler)
11             : base(url, handler)
12         {
13             
14         }
15          
16         public override VirtualPathData GetVirtualPath(RequestContext requestContext
17                                                           , RouteValueDictionary values)
18         {            
19             return base.GetVirtualPath(requestContext, values);
20         }
21         public override RouteData GetRouteData(HttpContextBase httpContext)
22         {            
23             return base.GetRouteData(httpContext);              
24         }
25 
26 
27         public string GetFieldFromContext(HttpContextBase httpContext,string fieldName)
28         {
29             return GetFieldFromRouteData(GetRouteData(httpContext), fieldName);
30         }
31         public string GetFieldFromRouteData(RouteData routeData,string fieldName)
32         {
33             if (routeData == null)
34                 throw new ArgumentNullException("routeData");
35              return routeData.GetRequiredString(fieldName);
36         }
37     }
1     //针对 .aspx内 生成相应路由名下的Url
2     public static  class RouteUrlHelper
3     {
获取 路由的 Url信息
 1         //根据参数表 自由匹配       
 2         public static string GetUrl(Dictionary<string,string> routeValueDic)
 3         {
 4             RouteValueDictionary parameters = new RouteValueDictionary(routeValueDic);
 5             VirtualPathData vpd = RouteTable.Routes.GetVirtualPath(null, parameters);
 6             return vpd.VirtualPath;
 7         }      
 8 
 9         public static string GetUrl(string routeName, Dictionary<string, object> routeValueDic)
10         {
11             RouteValueDictionary parameters = new RouteValueDictionary(routeValueDic);
12             return GetUrl(routeName, parameters);
13         }
14         public static string GetUrl(string routeName,object routeValue)
15         {
16             RouteValueDictionary parameters = new RouteValueDictionary(routeValue);
17             return GetUrl(routeName, parameters);
18         }
19         public static string GetUrl(string routeName,string[] routeKeys,string [] routeValues)
20         {
21             RouteValueDictionary parameters = new RouteValueDictionary();
22             int count=Math.Max(routeKeys.Length, routeValues.Length);
23             for(int i=0;i<count;i++)          
24             {
25                 parameters.Add(routeKeys[i], routeValues[i]);
26             }
27             return GetUrl(routeName, parameters);
28         }
29 
30         public static string GetUrl(string routeName, RouteValueDictionary routeValue)
31         {
32             var route=RouteTable.Routes[routeName];
33             if (route!=null)
34             {
35                 VirtualPathData vpd = RouteTable.Routes.GetVirtualPath(null, routeName, routeValue);
36                 return vpd.VirtualPath;                
37             }
38             return "";
39         }

Page 扩展方法 获取路由Url
 1  
 2         // 获取当前 Page 在某个路由下的Url表现
 3         public static string GetUrl(this Page page, string routeName)
 4         {
 5             return GetUrl(page, routeName, page.Request.RequestContext.RouteData.Values);
 6         }
 7 
 8         public static string GetUrl(this Page page, string routeName, object routeValue)
 9         {
10             return GetUrl(page, routeName, new RouteValueDictionary(routeValue));
11         }
12         public static string GetUrl(this Page page, string routeName, Dictionary<string, object> routeValue)
13         {
14             return GetUrl(page, routeName, new RouteValueDictionary(routeValue));
15         }
16         public static string GetUrl(this Page page, string routeName, RouteValueDictionary routeValue)
17         {
18             var route=(CustomRoute)RouteTable.Routes[routeName];
19             if (route!=null)
20             {
21                 VirtualPathData vpd =route.GetVirtualPath(page.Request.RequestContext, routeValue);
22                 return vpd.VirtualPath;
23             }
24             return "";
25         }
26  
其他工具方法
 1          public static Dictionary<string,string> GetRouteKeys(string routeName)
 2         {
 3             Route route=RouteTable.Routes[routeName] as Route;
 4             Dictionary<string,string> keyAndValues=new Dictionary<string,string>();
 5             if (route!=null)
 6             {
 7                 Regex reg=new Regex(@"\{([a-zA-Z0-9_]+)\}",RegexOptions.Compiled);
 8                var ms=reg.Matches(route.Url);
 9                foreach (Match m in ms)
10                {
11                    keyAndValues.Add(m.Groups[0].Value.Trim('{', '}'), "");
12                }                     
13             }
14             foreach (var item in route.Constraints)
15             {
16                 if (keyAndValues.ContainsKey(item.Key))
17                 {
18                     keyAndValues[item.Key]=item.Value.ToString();
19                 }
20             }
21             return keyAndValues;
22         }
23 
24         public static Dictionary<string,string> GetRouteDefaults(string routeName)
25         {
26             Route route=RouteTable.Routes[routeName] as Route;
27             Dictionary<string, string> defaults=new Dictionary<string, string>();
28             if (route!=null)
29             {
30                 if (route.Defaults!=null)
31                     foreach (var item in route.Defaults)
32                         defaults.Add(item.Key, item.Value.ToString());                  
33             }
34             return defaults;
35         }
36 
37         public static void SetRouteDefaultValue(string routeName,string paramName, string defaultValue)
38         {
39             Route route=RouteTable.Routes[routeName] as Route;
40             if (route!=null)
41             {
42                 if(route.Defaults.ContainsKey(paramName))
43                 {
44                     route.Defaults[paramName]=defaultValue;
45                 }
46             }
47         }
48 
49 
50         // 取页面中的 路由 参数值
51         public static string GetRouteValue(Page page,string fieldName)
52         {
53             return GetRouteValue(page.RouteData, fieldName);
54         }
55         public static string GetRouteValue(RouteData data, string fieldName)
56         {
57                object value;
58                if (data.Values.TryGetValue(fieldName, out value))
59                    return value.ToString();
60                return string.Empty;
61         }
4     }

 Global.asax.cs:

Global
 1  public class Global : System.Web.HttpApplication
 2     {
 3 
 4         public static void RegisterRoutes(RouteCollection routes)
 5         {   
 6             // 屏蔽 某些请求
 7             //routes.Add("ignor", new Route("route/onedetail/{id}", new StopRoutingHandler()));
 8             routes.Add("default", new CustomRoute("ShowDetail{Category}.tt")
 9             {   
10                 Defaults=new RouteValueDictionary(new{
11                     ViewName="Detail"
12                 }),
13                 Constraints = new RouteValueDictionary(new
14                 {
15                     Category="one|five"
16                 })
17             });
18             routes.Add("category", new CustomRoute("route/{Category}/{ViewName}.tt")
19                      { 
20                         ////约束取值
21                         Constraints = new RouteValueDictionary(new
22                         {
23                             ViewName="List|Detail|Edit|Insert|Delete" 
24                         })
25                      }
26                   );
27             routes.Add("addpre", new CustomRoute("route/{Category}/{Pre}/{ViewName}.tt")
28                 {
29                     RouteHandler=new PreRouteHandler(),
30                     Constraints = new RouteValueDictionary(new
31                     {
32                         ViewName="List|Detail|Edit|Insert|Delete"
33                     })
34                 }
35             );         
36 
37         }
38 
39         //传参数 对文件 就行数据绑定
40         public static void MapRoute(RouteCollection routes)
41         {  
42            // 若要设置 HTTP 谓词约束,可以将某个词典元素的值设置为 
43            //HttpMethodConstraint 对象,并将相关键设置为任何名称。
44             string[] allowedMethods = {"GET","POST"};
45             HttpMethodConstraint methodConstraints = new HttpMethodConstraint(allowedMethods);
46 
47             //测试:添加路由的顺序 越前面 优先级越高
48             //routes.MapPageRoute("youxianji",
49             //                 "route/onedetail/{id}",
50             //                 "~/HandlerFolder/two/detail.aspx");
51 
52 
53             //如果页面使用 Url:ShowDetailone.aspx  将不会传输Id 参数
54             routes.MapPageRoute("custom",
55                                "route/onedetail/{id}",
56                                "~/HandlerFolder/one/detail.aspx",
57                                false,
58                                new RouteValueDictionary { { "id", "101" } },// 默认取值 id=101
59                                new RouteValueDictionary { { "id", @"\d+" },{"httpMethod",methodConstraints}});
60 
61 
62 
63           
64         
65                               
66         }
67         void Application_Start(object sender, EventArgs e)
68         {
69              RegisterRoutes(RouteTable.Routes);
70              MapRoute(RouteTable.Routes);
71         }       
72     }

~/HandlerFolder/one/Detail.aspx.cs:

one/detail.aspx.cs
 1  public partial class Detail : System.Web.UI.Page
 2     {
 3         protected Dictionary<string, string> keyAndvalues;
 4         protected Dictionary<string,string> defaults;
 5 
 6         protected void Page_Load(object sender, EventArgs e)
 7         {  
 8             //通过路由来 生成Url地址       
 9             keyAndvalues=RouteUrlHelper.GetRouteKeys("addpre");
10 
11             defaults=RouteUrlHelper.GetRouteDefaults("custom");
12             // 数据绑定的参数
13             routedata.Text=Page.RouteData.Values["id"].ToString();
14             
15         }
16 
17         protected void btnChangeDefault_Click(object sender, EventArgs e)
18         {  
19             int id;
20             if(int.TryParse(RouteUrlHelper.GetRouteDefaults("custom")["id"],out id))
21                 id+=100;
22             else
23                 id=DateTime.Now.Millisecond;
24             RouteUrlHelper.SetRouteDefaultValue("custom", "id", id.ToString());
25         }
26     }

~/HandlerFolder/one/Detail.aspx:

one/detail.aspx.cs
 1 <html xmlns="http://www.w3.org/1999/xhtml">
 2 <head runat="server">
 3     <title></title>
 4 </head>
 5 <body>
 6     <form id="form1" runat="server">
 7     <div>    
 8      
 9      路由传递参数:
10      
11       <asp:Label runat="server" ID="routedata"></asp:Label>
12 
13     </div>
14     <div>
15     <br /><br />
16     根据路由名以及相对于的参数 获取对应的Url:<br />
17     <div><%=RouteBiz.RouteUrlHelper.GetUrl("addpre",new string[]{"Category","Pre","Viewname"},
18                                                     new string[]{"two", "QQ", "List"})%></div>
19     
20     <div><%=RouteBiz.RouteUrlHelper.GetUrl("category",new {Category="two",Viewname="delete"})%></div>
21      
22      <div><%=RouteBiz.RouteUrlHelper.GetUrl("custom",new {id="135"})%> </div>
23     
24      <br /><br />
25 
26      路由参数 以及限制的取值集合:<br />
27       <%foreach (var item in keyAndvalues)
28         {%>
29           <div><span> <%=item.Key %></span>::<span><%=item.Value %></span></div> 
30 
31       <%}%>
32 
33       <br /><br />
34       路由参数中的 默认值: <asp:Button ID="btnChangeDefault" runat="server" Text="ChangeRouteDefaultValue" 
35             onclick="btnChangeDefault_Click" />
36       <%foreach (var item in defaults)
37         { %>
38         <div> <%=item.Key%>  :: <%=item.Value %></div>
39       <%}%>
40     </div>
41     </form>
42 </body>
43 </html>

 [注意] HandlderFolder/two 下面的文件都是空文件,测试用的,如果相应的url ,查看是否能正常显示.

原文地址:https://www.cnblogs.com/AspDotNetMVC/p/2771667.html