using System; using System.Collections.Generic; using System.Linq; namespace Octokit { /// /// Extensions for working with Uris /// public static class UriExtensions { /// /// Merge a dictionary of values with an existing /// /// Original request Uri /// Collection of key-value pairs /// Updated request Uri public static Uri ApplyParameters(this Uri uri, IDictionary parameters) { Ensure.ArgumentNotNull(uri, "uri"); if (parameters == null || !parameters.Any()) return uri; // to prevent values being persisted across requests // use a temporary dictionary which combines new and existing parameters IDictionary p = new Dictionary(parameters); string queryString; if (uri.IsAbsoluteUri) { queryString = uri.Query; } else { var hasQueryString = uri.OriginalString.IndexOf("?", StringComparison.Ordinal); queryString = hasQueryString == -1 ? "" : uri.OriginalString.Substring(hasQueryString); } var values = queryString.Replace("?", "") .Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries); var existingParameters = values.ToDictionary( key => key.Substring(0, key.IndexOf('=')), value => value.Substring(value.IndexOf('=') + 1)); foreach (var existing in existingParameters) { if (!p.ContainsKey(existing.Key)) { p.Add(existing); } } Func mapValueFunc = (key, value) => key == "q" ? value : Uri.EscapeDataString(value); string query = string.Join("&", p.Select(kvp => kvp.Key + "=" + mapValueFunc(kvp.Key, kvp.Value))); if (uri.IsAbsoluteUri) { var uriBuilder = new UriBuilder(uri) { Query = query }; return uriBuilder.Uri; } return new Uri(uri + "?" + query, UriKind.Relative); } } }