As mentioned above, ASP. NET routing system has two main applications, one is to achieve the separation of request addresses and physical addresses by registering URL templates and matching physical file paths; the other is to generate a corresponding URL through the registered Routing test. The latter is implemented by calling the RouteCollection type GetVirtualPath method. [Download the source code from http://www.bkjia.com/uploadfile/2012/0322/2012032444439217.rar]
As shown in the following code snippet, GetVirtualPath defines two GetVirtualPath method overloading. The common parameters requestContext and values indicate the request context (RouteData and HTTP context encapsulation) and used to replace the value of the variable slot defined in the URL template. The other GetVirtualPath method has an additional string parameter name, which indicates the Registration name of the specific routing object used in the collection (the first parameter specified when the MapPageRoute method is called ). AppendTrailingSlash and LowercaseUrls determine whether to add a "/" character (if not) When standardizing the generated URL and whether to convert the URL to lowercase.
1: public class RouteCollection: Collection <RouteBase>
2 :{
3: // other members
4: public VirtualPathData GetVirtualPath (RequestContext requestContext, RouteValueDictionary values );
5: public VirtualPathData GetVirtualPath (RequestContext requestContext, string name, RouteValueDictionary values );
6:
7: public bool AppendTrailingSlash {get; set ;}
8: public bool LowercaseUrls {get; set ;}
9 :}
If no route object is specified when the GetVirtualPath method is called, each route object of the entire set is traversed and Its GetVirtualPath method is called. If the returned VirtualPathData is not Null, it is directly returned as the return value; otherwise (a matched route object cannot be found), Null is returned. If GetVirtualPath is called to determine the specific routing object used, the GetVirtualPath method of the route object is called directly and the execution result is returned.
When calling the GetVirtualPath method, we can pass Null as the first parameter (requestContext). In this case, it will be based on the Current HTTP context (corresponding to the static attribute Current of HttpContext) create a RequestContext object to call the same name parameter of the route object GetVirtualPath method. This parameter contains an empty RouteData object. If the current HTTP context does not exist, an InvalidOperationException is thrown.
The route matching of the route object for the GetVirtualPath method only requires that the values of the variables defined in the URL template can be provided, and these variable values have three sources, it is the default variable value defined by the route object, the variable value provided by RouteData of the specified RequestContext (Values attribute), and the manually provided variable value (RouteValueDictionary object specified by the values parameter ), the priority of these three variable values is from low to high. Take the previously defined URL template for weather information as an example. The following is the routing registration code.
1: public class Global: System. Web. HttpApplication
2 :{
3: protected void Application_Start (object sender, EventArgs e)
4 :{
5: var defaults = new RouteValueDictionary {"areacode", "010" },{ "days", 2 }};
6: var constaints = new RouteValueDictionary {"areacode", @ "0 \ d {2, 3}" },{ "days ", @ "[1-3] {1 }"}};
7: var dataTokens = new RouteValueDictionary {"defaultCity", "BeiJing" },{ "defaultDays", 2 }};
8: RouteTable. Routes. MapPageRoute ("default", "{areacode}/{days }","~ /Weather. aspx ", false, defaults, constaints, dataTokens );
9 :}
10 :}
In the background code of the Weather. aspx page, we use the following code to call the RouteTable and Routes familiar GetVirtualPath methods to generate three specific URLs.
1: public partial class Weather: Page
2 :{
3: protected void Page_Load (object sender, EventArgs e)
4 :{
5: RouteData routeData = new RouteData ();
6: routeData. Values. Add ("areaCode", "0512 ");
7: routeData. Values. Add ("days", "1 ");
8: RequestContext requestContext = new RequestContext ();
9: requestContext. HttpContext = new HttpContextWrapper (HttpContext. Current );
10: requestContext. RouteData = routeData;
11:
12: RouteValueDictionary values = new RouteValueDictionary ();
13: values. Add ("areaCode", "028 ");
14: values. Add ("days", "3 ");
15:
16: Response. Write (RouteTable. Routes. GetVirtualPath (null, null). VirtualPath + "<br/> ");
17: Response. Write (RouteTable. Routes. GetVirtualPath (requestContext, null). VirtualPath + "<br/> ");
18: Response. Write (RouteTable. Routes. GetVirtualPath (requestContext, values). VirtualPath + "<br/> ");
19 :}
20 :}
From the code snippet above, we can see that the requestContext and values parameters transmitted by calling the GetVirtualPath method for the first time are both Null, and a manually created RequestContext object is specified for the second time, its RouteData's Values attribute has two variables (areaCode = 0512; days = 1), while the values parameter is still Null. For the third time, we specify a specific object for the requestContext and values parameters at the same time, the latter contains two parameters (areaCode = 028; days = 3 ). Visit the Weather. aspx page in a browser and you will get the three URLs shown in. This fully confirms the conclusion above about the priority of variable selection.
Author: Artech