A utility for combining quests?
Is there a utility for combining querystrings? I am looking for something like:
Input: Combine("test=a&test2=b", "test3=c")
Result:"test=a&test2=b&test3=c"
Input: Combine("test=a&test2=b", "")
Result:"test=a&test2=b"
Input: Combine("", "test3=c")
Result:"test3=c"
And maybe some weird ones:
Input: Combine("&test=a&test2=b", "?test3=c")
Result:"test=a&test2=b&test3=c"
a source to share
I am using the following class to help me change and set query strings. While this won't solve your specific problem, you can use it and add a few more of your own functions to accomplish whatever you want. I just find it more convenient to treat query strings as IDictionary when I want to change them.
public static class QueryStringExtensions
{
/// <summary>
/// Creates a dictionary from a query string or other parameter collection
/// </summary>
/// <param name="queryString"></param>
/// <returns></returns>
public static IDictionary<string, string> ToDictionary(this NameValueCollection queryString)
{
var dict = new Dictionary<string, string>();
foreach (string key in queryString.Keys)
{
dict[key] = queryString[key];
}
return dict;
}
/// <summary>
/// Generates a query string from a dictionary
/// </summary>
/// <param name="dictionary"></param>
/// <returns></returns>
public static string ToQueryString(this IDictionary<string, string> dictionary)
{
if (dictionary.Count == 0) return "";
var items = new List<string>();
foreach (string key in dictionary.Keys)
{
items.Add(key + "=" + dictionary[key]);
}
return "?" + items.Concatenate("&");
}
/// <summary>
/// Generates a query stirng from a dictionary only using the keys in the keys parameter
/// </summary>
/// <param name="dictionary"></param>
/// <param name="keys"></param>
/// <returns></returns>
public static string ToQueryString(this IDictionary<string, string> dictionary, IEnumerable<string> keys)
{
var items = new List<string>();
foreach (string key in dictionary.Keys.Intersect(keys))
{
items.Add(key + "=" + dictionary[key]);
}
if (items.Count == 0) return "";
return "?" + items.Concatenate("&");
}
/// <summary>
/// joins an enumerable around a seperator.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="input"></param>
/// <param name="seperator"></param>
/// <returns></returns>
public static string Concatenate<T>(this IEnumerable<T> input, string seperator)
{
var ar = input.Select(i => i.ToString()).ToArray();
return string.Join(seperator, ar);
}
}
a source to share
Wouldn't this method work for you?
string Combine(string s1, string s2)
{
if(string.IsNullOrEmpty(s1)) return s2;
if(string.IsNullOrEmpty(s2)) return s1;
//several '?' at start are not expected so we can use TrimStart
return s1.TrimStart('?', '&') + "&" + s2.TrimStart('?', '&');
}
a source to share
I'm not sure if you get an out of the box solution for your requirement. You can use extension method as a way to achieve this. For more information on extension method see Extension Methods
a source to share
This is a .NET 4.0 solution due to the overload Join
that is in use and it is not completely out of the box. However, it uses .NET System.Web.HttpUtility
to parse requests correctly.
var r1 = HttpUtility.ParseQueryString("?test3=c");
var r2 = HttpUtility.ParseQueryString("");
var r3 = HttpUtility.ParseQueryString("test2=d");
var total = new NameValueCollection();
total.Add(r1);
total.Add(r2);
total.Add(r3);
var qs = String.Join(
"&",
total.AllKeys.Select(key => key + "=" + total[key]));
Console.WriteLine(qs);
Outputs:
// test3=c&test2=d
a source to share