A common task when calling web resources from a code is building a query string to including all the necessary parameters. While by all means no rocket science, there are some nifty details you need to take care of like, appending an &
if not the first parameter, encoding the parameters etc.
The code to do it is very simple, but a bit tedious:
StringBuilder SB = new StringBuilder();
if (NeedsToAddParameter A)
{
SB.Append("A="); SB.Append(HttpUtility.UrlEncode("TheValueOfA"));
}
if (NeedsToAddParameter B)
{
if (SB.Length>0) SB.Append("&");
SB.Append("B="); SB.Append(HttpUtility.UrlEncode("TheValueOfB")); }
}
This is such a common task one would expect a utility class to exist that makes it more elegant and readable. Scanning MSDN, I failed to find one—which brings me to the following question:
What is the most elegant clean way you know of doing the above?
This is the identical to the accepted answer except slightly more compact:
Works for multiple values per key in NameValueCollection.
ex:
{ {"k1", "v1"}, {"k1", "v1"} }
=>?k1=v1&k1=v1
With the inspiration from Roy Tinker's comment, I ended up using a simple extension method on the Uri class that keeps my code concise and clean:
Usage:
Edit - Standards compliant variant
As several people pointed out,
httpValueCollection.ToString()
encodes Unicode characters in a non-standards-compliant way. This is a variant of the same extension method that handles such characters by invokingHttpUtility.UrlEncode
method instead of the deprecatedHttpUtility.UrlEncodeUnicode
method.Add this class to your project
And use it like this:
I have an extension method for Uri that:
uri.WithQuery(new { name = "value" })
string/string
pairs (e.g. Dictionary`2).string/object
pairs (e.g. RouteValueDictionary).The documented version can be found here.
The extension:
The query parser:
Here are the tests:
I needed to solve the same problem for a portable class library (PCL) that I'm working on. In this case, I don't have access to System.Web so I can't use ParseQueryString.
Instead I used
System.Net.Http.FormUrlEncodedContent
like so: