internal string GetComponentsHelper(Uri uri, UriComponents components, UriFormat format) { UriElements elements = UriParseComponents.ParseComponents(uri.OriginalString.Trim(), UriKind.Absolute); string scheme = scheme_name; int dp = default_port; if ((scheme == null) || (scheme == "*")) { scheme = elements.scheme; dp = Uri.GetDefaultPort(scheme); } else if (String.Compare(scheme, elements.scheme, true) != 0) { throw new SystemException("URI Parser: scheme mismatch: " + scheme + " vs. " + elements.scheme); } var formatFlags = UriHelper.FormatFlags.None; if (UriHelper.HasCharactersToNormalize(uri.OriginalString)) { formatFlags |= UriHelper.FormatFlags.HasUriCharactersToNormalize; } if (uri.UserEscaped) { formatFlags |= UriHelper.FormatFlags.UserEscaped; } if (!string.IsNullOrEmpty(elements.host)) { formatFlags |= UriHelper.FormatFlags.HasHost; } // it's easier to answer some case directly (as the output isn't identical // when mixed with others components, e.g. leading slash, # ...) switch (components) { case UriComponents.Scheme: return(scheme); case UriComponents.UserInfo: return(elements.user ?? ""); case UriComponents.Host: return(elements.host); case UriComponents.Port: { int p = elements.port; if (p != null && p >= 0 && p != dp) { return(p.ToString(CultureInfo.InvariantCulture)); } return(String.Empty); } case UriComponents.Path: var path = elements.path; if (scheme != Uri.UriSchemeMailto && scheme != Uri.UriSchemeNews) { path = IgnoreFirstCharIf(elements.path, '/'); } return(UriHelper.FormatAbsolute(path, scheme, UriComponents.Path, format, formatFlags)); case UriComponents.Query: return(UriHelper.FormatAbsolute(elements.query, scheme, UriComponents.Query, format, formatFlags)); case UriComponents.Fragment: return(UriHelper.FormatAbsolute(elements.fragment, scheme, UriComponents.Fragment, format, formatFlags)); case UriComponents.StrongPort: { return(elements.port >= 0 ? elements.port.ToString(CultureInfo.InvariantCulture) : dp.ToString(CultureInfo.InvariantCulture)); } case UriComponents.SerializationInfoString: components = UriComponents.AbsoluteUri; break; } // now we deal with multiple flags... StringBuilder sb = new StringBuilder(); if ((components & UriComponents.Scheme) != 0) { sb.Append(scheme); sb.Append(elements.delimiter); } if ((components & UriComponents.UserInfo) != 0) { string userinfo = elements.user; if (userinfo != null) { sb.Append(elements.user); sb.Append('@'); } } if ((components & UriComponents.Host) != 0) { sb.Append(elements.host); } // for StrongPort always show port - even if -1 // otherwise only display if ut's not the default port if ((components & UriComponents.StrongPort) != 0) { sb.Append(":"); if (elements.port >= 0) { sb.Append(elements.port); } else { sb.Append(dp); } } if ((components & UriComponents.Port) != 0) { int p = elements.port; if (p != null && p >= 0 && p != dp) { sb.Append(":"); sb.Append(elements.port); } } if ((components & UriComponents.Path) != 0) { string path = elements.path; if ((components & UriComponents.PathAndQuery) != 0 && (path.Length == 0 || !path.StartsWith("/", StringComparison.Ordinal)) && elements.delimiter == Uri.SchemeDelimiter) { sb.Append("/"); } sb.Append(UriHelper.FormatAbsolute(path, scheme, UriComponents.Path, format, formatFlags)); } if ((components & UriComponents.Query) != 0) { string query = elements.query; if (query != null) { sb.Append("?"); sb.Append(UriHelper.FormatAbsolute(query, scheme, UriComponents.Query, format, formatFlags)); } } if ((components & UriComponents.Fragment) != 0) { string f = elements.fragment; if (f != null) { sb.Append("#"); sb.Append(UriHelper.FormatAbsolute(f, scheme, UriComponents.Fragment, format, formatFlags)); } } return(sb.ToString()); }