public static bool TryParseComponents(string uri, UriKind kind, out UriElements elements, out string error) { uri = uri.Trim(); ParserState state = new ParserState(uri, kind); elements = state.elements; error = null; if (uri.Length == 0 && (kind == UriKind.Relative || kind == UriKind.RelativeOrAbsolute)) { state.elements.isAbsoluteUri = false; return true; } if (uri.Length <= 1 && kind == UriKind.Absolute) { error = "Absolute URI is too short"; return false; } bool ok = ParseFilePath(state) && ParseScheme(state); var scheme = state.elements.scheme; UriParser parser = null; if (!StringUtilities.IsNullOrEmpty(scheme)) { parser = UriParser.GetParser(scheme); if (parser != null && !(parser is DefaultUriParser)) return true; } ok = ok && ParseAuthority(state) && ParsePath(state) && ParseQuery(state) && ParseFragment(state); if (StringUtilities.IsNullOrEmpty(state.elements.host) && (scheme == Uri.UriSchemeHttp || scheme == Uri.UriSchemeGopher || scheme == Uri.UriSchemeNntp || scheme == Uri.UriSchemeHttps || scheme == Uri.UriSchemeFtp)) state.error = "Invalid URI: The Authority/Host could not be parsed."; if (!StringUtilities.IsNullOrEmpty(state.elements.host) && Uri.CheckHostName(state.elements.host) == UriHostNameType.Unknown) state.error = "Invalid URI: The hostname could not be parsed."; if (!StringUtilities.IsNullOrEmpty(state.error)) { elements = null; error = state.error; return false; } return true; }
public ParserState(string uri, UriKind kind) { remaining = uri; this.kind = kind; elements = new UriElements(); }