public virtual VirtualPathData?GetVirtualPath(VirtualPathContext context) { EnsureOptions(context.HttpContext); if (!string.IsNullOrEmpty(context.RouteName)) { VirtualPathData?namedRoutePathData = null; if (_namedRoutes.TryGetValue(context.RouteName, out var matchedNamedRoute)) { namedRoutePathData = matchedNamedRoute.GetVirtualPath(context); } var pathData = GetVirtualPath(context, _unnamedRoutes); // If the named route and one of the unnamed routes also matches, then we have an ambiguity. if (namedRoutePathData != null && pathData != null) { var message = Resources.FormatNamedRoutes_AmbiguousRoutesFound(context.RouteName); throw new InvalidOperationException(message); } return(NormalizeVirtualPath(namedRoutePathData ?? pathData)); } else { return(NormalizeVirtualPath(GetVirtualPath(context, _routes))); } }
private VirtualPathData?NormalizeVirtualPath(VirtualPathData?pathData) { if (pathData == null) { return(pathData); } Debug.Assert(_options != null); var url = pathData.VirtualPath; if (!string.IsNullOrEmpty(url) && (_options.LowercaseUrls || _options.AppendTrailingSlash)) { var indexOfSeparator = url.IndexOfAny(UrlQueryDelimiters); var urlWithoutQueryString = url; var queryString = string.Empty; if (indexOfSeparator != -1) { urlWithoutQueryString = url.Substring(0, indexOfSeparator); queryString = url.Substring(indexOfSeparator); } if (_options.LowercaseUrls) { urlWithoutQueryString = urlWithoutQueryString.ToLowerInvariant(); } if (_options.LowercaseUrls && _options.LowercaseQueryStrings) { queryString = queryString.ToLowerInvariant(); } if (_options.AppendTrailingSlash && !urlWithoutQueryString.EndsWith("/", StringComparison.Ordinal)) { urlWithoutQueryString += "/"; } // queryString will contain the delimiter ? or # as the first character, so it's safe to append. url = urlWithoutQueryString + queryString; return(new VirtualPathData(pathData.Router, url, pathData.DataTokens)); } return(pathData); }
/// <summary> /// Generates the URL using the specified components. /// </summary> /// <param name="protocol">The protocol for the URL, such as "http" or "https".</param> /// <param name="host">The host name for the URL.</param> /// <param name="pathData">The <see cref="VirtualPathData"/>.</param> /// <param name="fragment">The fragment for the URL.</param> /// <returns>The generated URL.</returns> protected virtual string?GenerateUrl(string?protocol, string?host, VirtualPathData?pathData, string?fragment) { return(GenerateUrl(protocol, host, pathData?.VirtualPath, fragment)); }