public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary routeValues) { // Lookup best match for route values in the expanded tree var match = _aliasMap.Locate(routeValues); if (match != null) { // Build any "spare" route values onto the Alias (so we correctly support any additional query parameters) var sb = new StringBuilder(match.Item2); var extra = 0; foreach (var routeValue in routeValues) { // Ignore any we already have if (match.Item1.ContainsKey(routeValue.Key)) { continue; } // Add a query string fragment sb.Append((extra++ == 0) ? '?' : '&'); sb.Append(Uri.EscapeDataString(routeValue.Key)); sb.Append('='); sb.Append(Uri.EscapeDataString(Convert.ToString(routeValue.Value, CultureInfo.InvariantCulture))); } // Construct data var data = new VirtualPathData(this, sb.ToString()); // Set the Area for this route data.DataTokens["area"] = Area; return(data); } return(null); }