C# 89" } }; var newUrl=newuri(queryhelp.AddQueryString(url,param)); 公共静态字符串ToQueryString(此字典源代码) { 返回String.Join(“&”,source.Select(kvp=>String.Format(“{0}={1}”),HttpUtility.UrlEncode(kvp.Key),HttpUtility.UrlEncode(kvp.Value)).ToArray(); } 公共静态字符串ToQueryString(此NameValueCollection源) { 返回String.Join(“&”,source.Cast().Select(key=>String.Format(“{0}={1}”),HttpUtility.UrlEncode(key),HttpUtility.UrlEncode(source[key])).ToArray(); }
这是我迟来的作品。由于各种原因,我不喜欢其他作品,所以我写了自己的作品 此版本的特点是:C# 89" } }; var newUrl=newuri(queryhelp.AddQueryString(url,param)); 公共静态字符串ToQueryString(此字典源代码) { 返回String.Join(“&”,source.Select(kvp=>String.Format(“{0}={1}”),HttpUtility.UrlEncode(kvp.Key),HttpUtility.UrlEncode(kvp.Value)).ToArray(); } 公共静态字符串ToQueryString(此NameValueCollection源) { 返回String.Join(“&”,source.Cast().Select(key=>String.Format(“{0}={1}”),HttpUtility.UrlEncode(key),HttpUtility.UrlEncode(source[key])).ToArray(); },c#,.net,url,query-string,C#,.net,Url,Query String,这是我迟来的作品。由于各种原因,我不喜欢其他作品,所以我写了自己的作品 此版本的特点是: 仅使用StrugBu建器。没有ToRayAuy()调用或其他扩展方法。它看起来不像其他的一些响应一样漂亮,但我认为这是一个核心函数,所以效率比隐藏“低效”的“流畅”、“一行”代码更重要。 处理每个键的多个值。(我自己不需要它,只是为了使Mauricio;) 示例用法 输出 HttpValueCollection的可链包装类: namespace System.Web.Mvc { public
-
仅使用StrugBu建器。没有ToRayAuy()调用或其他扩展方法。它看起来不像其他的一些响应一样漂亮,但我认为这是一个核心函数,所以效率比隐藏“低效”的“流畅”、“一行”代码更重要。
- 处理每个键的多个值。(我自己不需要它,只是为了使Mauricio;)
HttpValueCollection的可链包装类:
namespace System.Web.Mvc {
public class QueryStringBuilder {
private NameValueCollection collection;
public QueryStringBuilder() {
collection = System.Web.HttpUtility.ParseQueryString(string.Empty);
}
public QueryStringBuilder Add(string key, string value) {
collection.Add(key, value);
return this;
}
public QueryStringBuilder Remove(string key) {
collection.Remove(key);
return this;
}
public string this[string key] {
get { return collection[key]; }
set { collection[key] = value; }
}
public string ToString() {
return collection.ToString();
}
}
}
用法示例:
QueryStringBuilder parameters = new QueryStringBuilder()
.Add("view", ViewBag.PageView)
.Add("page", ViewBag.PageNumber)
.Add("size", ViewBag.PageSize);
string queryString = parameters.ToString();
我使用其他答案中的一些提示为我的razor项目编写了一个助手 ParseQueryString业务是必需的,因为我们不允许篡改当前请求的QueryString对象
@helper GetQueryStringWithValue(string key, string value) {
var queryString = System.Web.HttpUtility.ParseQueryString(HttpContext.Current.Request.QueryString.ToString());
queryString[key] = value;
@Html.Raw(queryString.ToString())
}
我是这样使用它的:
location.search = '?@Helpers.GetQueryStringWithValue("var-name", "var-value")';
var actual = new QueryStringBuilder {
{"foo", 123},
{"bar", "val31"},
{"bar", "val32"}
};
actual.Add("a+b", "c+d");
actual.ToString(); // "foo=123&bar=val31&bar=val32&a%2bb=c%2bd"
如果您希望它接受多个值,只需将参数更改为字典,并将对添加到查询字符串中。这里有一个fluent/lambda-ish方法作为扩展方法(结合前面文章中的概念)这支持同一个密钥的多个值。我个人的偏好是,其他团队成员可以通过扩展而不是包装来发现类似的东西。请注意,编码方法存在争议,在堆栈溢出(Stack Overflow)和MSDN bloggers(如)上有很多关于它的帖子 编辑:使用空支持,不过您可能需要根据您的特定情况对其进行调整
public static string ToQueryString(this NameValueCollection source, bool removeEmptyEntries)
{
return source != null ? String.Join("&", source.AllKeys
.Where(key => !removeEmptyEntries || source.GetValues(key)
.Where(value => !String.IsNullOrEmpty(value))
.Any())
.SelectMany(key => source.GetValues(key)
.Where(value => !removeEmptyEntries || !String.IsNullOrEmpty(value))
.Select(value => String.Format("{0}={1}", HttpUtility.UrlEncode(key), value != null ? HttpUtility.UrlEncode(value) : string.Empty)))
.ToArray())
: string.Empty;
}
我写了一些扩展方法,我发现这些方法在使用QueryString时非常有用。通常我想从当前QueryString开始,在使用它之前进行修改。比如
var res = Request.QueryString.Duplicate()
.ChangeField("field1", "somevalue")
.ChangeField("field2", "only if following is true", true)
.ChangeField("id", id, id>0)
.WriteLocalPathWithQuery(Request.Url)); //Uses context to write the path
有关更多信息和来源:
这是基本的,但我喜欢这种风格。受Roy Tinker评论的启发,我最终在Uri类上使用了一种简单的扩展方法,使代码简洁明了:
using System.Web;
public static class HttpExtensions
{
public static Uri AddQuery(this Uri uri, string name, string value)
{
var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);
httpValueCollection.Remove(name);
httpValueCollection.Add(name, value);
var ub = new UriBuilder(uri);
ub.Query = httpValueCollection.ToString();
return ub.Uri;
}
}
用法:
Uri url = new Uri("http://localhost/rest/something/browse").
AddQuery("page", "0").
AddQuery("pageSize", "200");
var uri = new Uri("http://stackoverflow.com").AddQuery("such", "method")
.AddQuery("wow", "soFluent");
// http://stackoverflow.com?such=method&wow=soFluent
编辑-符合标准的变体
正如一些人指出的,
httpValueCollection.ToString()
以某种方式对Unicode字符进行编码。这是通过调用HttpUtility.UrlEncode
方法而不是不推荐的HttpUtility.urlencodeucode
方法来处理此类字符的同一扩展方法的变体
using System.Web;
public static Uri AddQuery(this Uri uri, string name, string value)
{
var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);
httpValueCollection.Remove(name);
httpValueCollection.Add(name, value);
var ub = new UriBuilder(uri);
// this code block is taken from httpValueCollection.ToString() method
// and modified so it encodes strings with HttpUtility.UrlEncode
if (httpValueCollection.Count == 0)
ub.Query = String.Empty;
else
{
var sb = new StringBuilder();
for (int i = 0; i < httpValueCollection.Count; i++)
{
string text = httpValueCollection.GetKey(i);
{
text = HttpUtility.UrlEncode(text);
string val = (text != null) ? (text + "=") : string.Empty;
string[] vals = httpValueCollection.GetValues(i);
if (sb.Length > 0)
sb.Append('&');
if (vals == null || vals.Length == 0)
sb.Append(val);
else
{
if (vals.Length == 1)
{
sb.Append(val);
sb.Append(HttpUtility.UrlEncode(vals[0]));
}
else
{
for (int j = 0; j < vals.Length; j++)
{
if (j > 0)
sb.Append('&');
sb.Append(val);
sb.Append(HttpUtility.UrlEncode(vals[j]));
}
}
}
}
}
ub.Query = sb.ToString();
}
return ub.Uri;
}
使用System.Web;
公共静态Uri AddQuery(此Uri、字符串名称、字符串值)
{
var httpValueCollection=HttpUtility.ParseQueryString(uri.Query);
httpValueCollection.Remove(名称);
httpValueCollection.Add(名称、值);
var ub=新的UriBuilder(uri);
//此代码块取自httpValueCollection.ToString()方法
//并修改为使用HttpUtility.UrlEncode对字符串进行编码
if(httpValueCollection.Count==0)
ub.Query=String.Empty;
其他的
{
var sb=新的StringBuilder();
对于(int i=0;i0)
某人附加('&');
如果(VAL==null | | VAL.Length==0)
附加某人(val);
其他的
{
如果(vals.Length==1)
{
附加某人(val);
sb.Append(HttpUtility.UrlEncode(vals[0]);
}
其他的
{
对于(int j=0;j0)
某人附加('&');
附加某人(val);
sb.Append(HttpUtility.UrlEncode(vals[j]);
}
}
}
}
}
ub.Query=sb.ToString();
}
返回ub.Uri;
}
下面的代码是通过ILSpy从HttpValueCollection
实现的ToString
中提取出来的,ILSpy为您提供了一个name=value querystring
不幸的是,HttpValueCollection是一个内部类,只有在使用
HttpUtility.ParseQueryString()
时才能返回。我删除了它的所有viewstate部分,默认情况下它进行编码:
public static class HttpExtensions
{
public static string ToQueryString(this NameValueCollection collection)
{
// This is based off the NameValueCollection.ToString() implementation
int count = collection.Count;
if (count == 0)
return string.Empty;
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < count; i++)
{
string text = collection.GetKey(i);
text = HttpUtility.UrlEncodeUnicode(text);
string value = (text != null) ? (text + "=") : string.Empty;
string[] values = collection.GetValues(i);
if (stringBuilder.Length > 0)
{
stringBuilder.Append('&');
}
if (values == null || values.Length == 0)
{
stringBuilder.Append(value);
}
else
{
if (values.Length == 1)
{
stringBuilder.Append(value);
string text2 = values[0];
text2 = HttpUtility.UrlEncodeUnicode(text2);
stringBuilder.Append(text2);
}
else
{
for (int j = 0; j < values.Length; j++)
{
if (j > 0)
{
stringBuilder.Append('&');
}
stringBuilder.Append(value);
string text2 = values[j];
text2 = HttpUtility.UrlEncodeUnicode(text2);
stringBuilder.Append(text2);
}
}
}
}
return stringBuilder.ToString();
}
}
公共静态类HttpExtensions
{
公共静态字符串ToQueryString(此NameValueCollection集合)
{
//这是基于NameValueCollection.ToString()实现的
int count=collection.count;
如果(计数=0)
返回字符串。空;
StringBuilder StringBuilder=新的StringBuilder();
for(int i=0;i0)
{
stringBuilder.Append('&');
}
如果(值==null | |值。长度==0)
{
stringBuilder.Append(值);
}
其他的
{
const string url = "https://customer-information.azure-api.net/customers/search/taxnbr";
var param = new Dictionary<string, string>() { { "CIKey", "123456789" } };
var newUrl = new Uri(QueryHelpers.AddQueryString(url, param));
public static string ToQueryString(this Dictionary<string, string> source)
{
return String.Join("&", source.Select(kvp => String.Format("{0}={1}", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value))).ToArray());
}
public static string ToQueryString(this NameValueCollection source)
{
return String.Join("&", source.Cast<string>().Select(key => String.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(source[key]))).ToArray());
}
public string ToQueryString(NameValueCollection nvc)
{
StringBuilder sb = new StringBuilder("?");
bool first = true;
foreach (string key in nvc.AllKeys)
{
foreach (string value in nvc.GetValues(key))
{
if (!first)
{
sb.Append("&");
}
sb.AppendFormat("{0}={1}", Uri.EscapeDataString(key), Uri.EscapeDataString(value));
first = false;
}
}
return sb.ToString();
}
var queryParams = new NameValueCollection()
{
{ "x", "1" },
{ "y", "2" },
{ "foo", "bar" },
{ "foo", "baz" },
{ "special chars", "? = &" },
};
string url = "http://example.com/stuff" + ToQueryString(queryParams);
Console.WriteLine(url);
http://example.com/stuff?x=1&y=2&foo=bar&foo=baz&special%20chars=%3F%20%3D%20%26
namespace System.Web.Mvc {
public class QueryStringBuilder {
private NameValueCollection collection;
public QueryStringBuilder() {
collection = System.Web.HttpUtility.ParseQueryString(string.Empty);
}
public QueryStringBuilder Add(string key, string value) {
collection.Add(key, value);
return this;
}
public QueryStringBuilder Remove(string key) {
collection.Remove(key);
return this;
}
public string this[string key] {
get { return collection[key]; }
set { collection[key] = value; }
}
public string ToString() {
return collection.ToString();
}
}
}
QueryStringBuilder parameters = new QueryStringBuilder()
.Add("view", ViewBag.PageView)
.Add("page", ViewBag.PageNumber)
.Add("size", ViewBag.PageSize);
string queryString = parameters.ToString();
@helper GetQueryStringWithValue(string key, string value) {
var queryString = System.Web.HttpUtility.ParseQueryString(HttpContext.Current.Request.QueryString.ToString());
queryString[key] = value;
@Html.Raw(queryString.ToString())
}
location.search = '?@Helpers.GetQueryStringWithValue("var-name", "var-value")';
public static string ToQueryString(this NameValueCollection source)
{
return String.Join("&", source.AllKeys
.SelectMany(key => source.GetValues(key)
.Select(value => String.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value))))
.ToArray());
}
public static string ToQueryString(this NameValueCollection source, bool removeEmptyEntries)
{
return source != null ? String.Join("&", source.AllKeys
.Where(key => !removeEmptyEntries || source.GetValues(key)
.Where(value => !String.IsNullOrEmpty(value))
.Any())
.SelectMany(key => source.GetValues(key)
.Where(value => !removeEmptyEntries || !String.IsNullOrEmpty(value))
.Select(value => String.Format("{0}={1}", HttpUtility.UrlEncode(key), value != null ? HttpUtility.UrlEncode(value) : string.Empty)))
.ToArray())
: string.Empty;
}
var res = Request.QueryString.Duplicate()
.ChangeField("field1", "somevalue")
.ChangeField("field2", "only if following is true", true)
.ChangeField("id", id, id>0)
.WriteLocalPathWithQuery(Request.Url)); //Uses context to write the path
using System.Web;
public static class HttpExtensions
{
public static Uri AddQuery(this Uri uri, string name, string value)
{
var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);
httpValueCollection.Remove(name);
httpValueCollection.Add(name, value);
var ub = new UriBuilder(uri);
ub.Query = httpValueCollection.ToString();
return ub.Uri;
}
}
Uri url = new Uri("http://localhost/rest/something/browse").
AddQuery("page", "0").
AddQuery("pageSize", "200");
using System.Web;
public static Uri AddQuery(this Uri uri, string name, string value)
{
var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);
httpValueCollection.Remove(name);
httpValueCollection.Add(name, value);
var ub = new UriBuilder(uri);
// this code block is taken from httpValueCollection.ToString() method
// and modified so it encodes strings with HttpUtility.UrlEncode
if (httpValueCollection.Count == 0)
ub.Query = String.Empty;
else
{
var sb = new StringBuilder();
for (int i = 0; i < httpValueCollection.Count; i++)
{
string text = httpValueCollection.GetKey(i);
{
text = HttpUtility.UrlEncode(text);
string val = (text != null) ? (text + "=") : string.Empty;
string[] vals = httpValueCollection.GetValues(i);
if (sb.Length > 0)
sb.Append('&');
if (vals == null || vals.Length == 0)
sb.Append(val);
else
{
if (vals.Length == 1)
{
sb.Append(val);
sb.Append(HttpUtility.UrlEncode(vals[0]));
}
else
{
for (int j = 0; j < vals.Length; j++)
{
if (j > 0)
sb.Append('&');
sb.Append(val);
sb.Append(HttpUtility.UrlEncode(vals[j]));
}
}
}
}
}
ub.Query = sb.ToString();
}
return ub.Uri;
}
public static class HttpExtensions
{
public static string ToQueryString(this NameValueCollection collection)
{
// This is based off the NameValueCollection.ToString() implementation
int count = collection.Count;
if (count == 0)
return string.Empty;
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < count; i++)
{
string text = collection.GetKey(i);
text = HttpUtility.UrlEncodeUnicode(text);
string value = (text != null) ? (text + "=") : string.Empty;
string[] values = collection.GetValues(i);
if (stringBuilder.Length > 0)
{
stringBuilder.Append('&');
}
if (values == null || values.Length == 0)
{
stringBuilder.Append(value);
}
else
{
if (values.Length == 1)
{
stringBuilder.Append(value);
string text2 = values[0];
text2 = HttpUtility.UrlEncodeUnicode(text2);
stringBuilder.Append(text2);
}
else
{
for (int j = 0; j < values.Length; j++)
{
if (j > 0)
{
stringBuilder.Append('&');
}
stringBuilder.Append(value);
string text2 = values[j];
text2 = HttpUtility.UrlEncodeUnicode(text2);
stringBuilder.Append(text2);
}
}
}
}
return stringBuilder.ToString();
}
}
private string ToQueryString(NameValueCollection nvc)
{
return "?" + string.Join("&", nvc.AllKeys.Select(k => string.Format("{0}={1}",
HttpUtility.UrlEncode(k),
HttpUtility.UrlEncode(nvc[k]))));
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class QueryStringBuilder
{
private readonly List<KeyValuePair<string, object>> _list;
public QueryStringBuilder()
{
_list = new List<KeyValuePair<string, object>>();
}
public void Add(string name, object value)
{
_list.Add(new KeyValuePair<string, object>(name, value));
}
public override string ToString()
{
return String.Join("&", _list.Select(kvp => String.Concat(Uri.EscapeDataString(kvp.Key), "=", Uri.EscapeDataString(kvp.Value.ToString()))));
}
}
var actual = new QueryStringBuilder {
{"foo", 123},
{"bar", "val31"},
{"bar", "val32"}
};
actual.Add("a+b", "c+d");
actual.ToString(); // "foo=123&bar=val31&bar=val32&a%2bb=c%2bd"
public static class HttpClientExt
{
public static Uri AddQueryParams(this Uri uri, string query)
{
var ub = new UriBuilder(uri);
ub.Query = string.IsNullOrEmpty(uri.Query) ? query : string.Join("&", uri.Query.Substring(1), query);
return ub.Uri;
}
public static Uri AddQueryParams(this Uri uri, IEnumerable<string> query)
{
return uri.AddQueryParams(string.Join("&", query));
}
public static Uri AddQueryParams(this Uri uri, string key, string value)
{
return uri.AddQueryParams(string.Join("=", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value)));
}
public static Uri AddQueryParams(this Uri uri, params KeyValuePair<string,string>[] kvps)
{
return uri.AddQueryParams(kvps.Select(kvp => string.Join("=", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value))));
}
public static Uri AddQueryParams(this Uri uri, IDictionary<string, string> kvps)
{
return uri.AddQueryParams(kvps.Select(kvp => string.Join("=", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value))));
}
public static Uri AddQueryParams(this Uri uri, NameValueCollection nvc)
{
return uri.AddQueryParams(nvc.AllKeys.SelectMany(nvc.GetValues, (key, value) => string.Join("=", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value))));
}
}
var uri = new Uri("https://api.del.icio.us/v1/posts/suggest").AddQueryParam("url","http://stackoverflow.com")
public static Uri AddQuery(this Uri uri, string name, string value)
{
// this actually returns HttpValueCollection : NameValueCollection
// which uses unicode compliant encoding on ToString()
var query = HttpUtility.ParseQueryString(uri.Query);
query.Add(name, value);
var uriBuilder = new UriBuilder(uri)
{
Query = query.ToString()
};
return uriBuilder.Uri;
}
var uri = new Uri("http://stackoverflow.com").AddQuery("such", "method")
.AddQuery("wow", "soFluent");
// http://stackoverflow.com?such=method&wow=soFluent
var url = "http://www.some-api.com".SetQueryParams(new
{
api_key = ConfigurationManager.AppSettings["SomeApiKey"],
max_results = 20,
q = "Don't worry, I'll get encoded!"
});
T result = await "https://api.mysite.com"
.AppendPathSegment("person")
.SetQueryParams(new { ap_key = "my-key" })
.WithOAuthBearerToken("MyToken")
.PostJsonAsync(new { first_name = firstName, last_name = lastName })
.ReceiveJson<T>();
private string ToQueryString(NameValueCollection nvc)
{
if (nvc == null) return String.Empty;
var queryParams =
string.Join("&", nvc.AllKeys.Select(key =>
string.Join("&", nvc.GetValues(key).Select(v => string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(v))))));
return "?" + queryParams;
}
var url = new UriBuilder("http://example.com");
url.Query = new FormUrlEncodedContent(new Dictionary<string,string>()
{
{"param1", "val1"},
{"param2", "val2"},
{"param3", "val3"},
}).ReadAsStringAsync().Result;
var queryString = HttpUtility2.BuildQueryString(new
{
key2 = "value2",
key1 = "value1",
});
public static class HttpUtility2
{
public static string BuildQueryString<T>(T obj)
{
var queryString = HttpUtility.ParseQueryString(string.Empty);
foreach (var property in TypeDescriptor.GetProperties(typeof(T)).Cast<PropertyDescriptor>())
{
var value = (property.GetValue(obj) ?? "").ToString();
queryString.Add(property.Name, value);
}
return queryString.ToString();
}
}
public class UrlBuilder
{
#region Variables / Properties
private readonly StringBuilder _builder;
#endregion Variables / Properties
#region Constructor
public UrlBuilder(string urlBase)
{
_builder = new StringBuilder(urlBase);
}
#endregion Constructor
#region Methods
public UrlBuilder AppendParameter(string paramName, string value)
{
if (_builder.ToString().Contains("?"))
_builder.Append("&");
else
_builder.Append("?");
_builder.Append(HttpUtility.UrlEncode(paramName));
_builder.Append("=");
_builder.Append(HttpUtility.UrlEncode(value));
return this;
}
public override string ToString()
{
return _builder.ToString();
}
#endregion Methods
}
string url = new UrlBuilder("http://www.somedomain.com/")
.AppendParameter("a", "true")
.AppendParameter("b", "muffin")
.AppendParameter("c", "muffin button")
.ToString();
// Result: http://www.somedomain.com?a=true&b=muffin&c=muffin%20button
public static Uri WithQuery(this Uri uri, object values)
{
if (uri == null)
throw new ArgumentNullException(nameof(uri));
if (values != null)
{
var query = string.Join(
"&", from p in ParseQueryValues(values)
where !string.IsNullOrWhiteSpace(p.Key)
let k = HttpUtility.UrlEncode(p.Key.Trim())
let v = HttpUtility.UrlEncode(p.Value)
orderby k
select string.IsNullOrEmpty(v) ? k : $"{k}={v}");
if (query.Length != 0 || uri.Query.Length != 0)
uri = new UriBuilder(uri) { Query = query }.Uri;
}
return uri;
}
private static IEnumerable<KeyValuePair<string, string>> ParseQueryValues(object values)
{
// Check if a name/value collection.
var nvc = values as NameValueCollection;
if (nvc != null)
return from key in nvc.AllKeys
from val in nvc.GetValues(key)
select new KeyValuePair<string, string>(key, val);
// Check if a string/string dictionary.
var ssd = values as IEnumerable<KeyValuePair<string, string>>;
if (ssd != null)
return ssd;
// Check if a string/object dictionary.
var sod = values as IEnumerable<KeyValuePair<string, object>>;
if (sod == null)
{
// Check if a non-generic dictionary.
var ngd = values as IDictionary;
if (ngd != null)
sod = ngd.Cast<dynamic>().ToDictionary<dynamic, string, object>(
p => p.Key.ToString(), p => p.Value as object);
// Convert object properties to dictionary.
if (sod == null)
sod = new RouteValueDictionary(values);
}
// Normalize and return the values.
return from pair in sod
from val in pair.Value as IEnumerable<string>
?? new[] { pair.Value?.ToString() }
select new KeyValuePair<string, string>(pair.Key, val);
}
var uri = new Uri("https://stackoverflow.com/yo?oldKey=oldValue");
// Test with a string/string dictionary.
var q = uri.WithQuery(new Dictionary<string, string>
{
["k1"] = string.Empty,
["k2"] = null,
["k3"] = "v3"
});
Debug.Assert(q == new Uri(
"https://stackoverflow.com/yo?k1&k2&k3=v3"));
// Test with a string/object dictionary.
q = uri.WithQuery(new Dictionary<string, object>
{
["k1"] = "v1",
["k2"] = new[] { "v2a", "v2b" },
["k3"] = null
});
Debug.Assert(q == new Uri(
"https://stackoverflow.com/yo?k1=v1&k2=v2a&k2=v2b&k3"));
// Test with a name/value collection.
var nvc = new NameValueCollection()
{
["k1"] = string.Empty,
["k2"] = "v2a"
};
nvc.Add("k2", "v2b");
q = uri.WithQuery(nvc);
Debug.Assert(q == new Uri(
"https://stackoverflow.com/yo?k1&k2=v2a&k2=v2b"));
// Test with any dictionary.
q = uri.WithQuery(new Dictionary<int, HashSet<string>>
{
[1] = new HashSet<string> { "v1" },
[2] = new HashSet<string> { "v2a", "v2b" },
[3] = null
});
Debug.Assert(q == new Uri(
"https://stackoverflow.com/yo?1=v1&2=v2a&2=v2b&3"));
// Test with an anonymous object.
q = uri.WithQuery(new
{
k1 = "v1",
k2 = new[] { "v2a", "v2b" },
k3 = new List<string> { "v3" },
k4 = true,
k5 = null as Queue<string>
});
Debug.Assert(q == new Uri(
"https://stackoverflow.com/yo?k1=v1&k2=v2a&k2=v2b&k3=v3&k4=True&k5"));
// Keep existing query using a name/value collection.
nvc = HttpUtility.ParseQueryString(uri.Query);
nvc.Add("newKey", "newValue");
q = uri.WithQuery(nvc);
Debug.Assert(q == new Uri(
"https://stackoverflow.com/yo?newKey=newValue&oldKey=oldValue"));
// Merge two query objects using the RouteValueDictionary.
var an1 = new { k1 = "v1" };
var an2 = new { k2 = "v2" };
q = uri.WithQuery(
new RouteValueDictionary(an1).Concat(
new RouteValueDictionary(an2)));
Debug.Assert(q == new Uri(
"https://stackoverflow.com/yo?k1=v1&k2=v2"));
// USAGE
[TestMethod]
public void TestUrlBuilder()
{
Console.WriteLine(
new UrlBuilder("http://www.google.com?A=B")
.AddPath("SomePathName")
.AddPath("AnotherPathName")
.SetQuery("SomeQueryKey", "SomeQueryValue")
.AlterQuery("A", x => x + "C"));
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
// By Demetris Leptos
namespace TheOperator.Foundation.Web
{
public class UrlBuilder
{
public string Scheme { get; set; }
public string Host { get; set; }
public int? Port { get; set; }
public List<string> Paths { get; set; }
public SortedDictionary<string, string> QueryPairs { get; set; }
public UrlBuilder(string url)
{
this.Paths = new List<string>();
this.QueryPairs = new SortedDictionary<string, string>();
string path = null;
string query = null;
Uri relativeUri = null;
if (!Uri.TryCreate(url, UriKind.Relative, out relativeUri))
{
var uriBuilder = new UriBuilder(url);
this.Scheme = uriBuilder.Scheme;
this.Host = uriBuilder.Host;
this.Port = uriBuilder.Port;
path = uriBuilder.Path;
query = uriBuilder.Query;
}
else
{
var queryIndex = url.IndexOf('?');
if (queryIndex >= 0)
{
path = url.Substring(0, queryIndex);
query = url.Substring(queryIndex + 1);
}
else
{
path = url;
}
}
this.Paths.AddRange(path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries));
if (query != null)
{
var queryKeyValuePairs = HttpUtility.ParseQueryString(query);
foreach (var queryKey in queryKeyValuePairs.AllKeys)
{
this.QueryPairs[queryKey] = queryKeyValuePairs[queryKey];
}
}
}
public UrlBuilder AddPath(string value)
{
this.Paths.Add(value);
return this;
}
public UrlBuilder SetQuery(string key, string value)
{
this.QueryPairs[key] = value;
return this;
}
public UrlBuilder RemoveQuery(string key)
{
this.QueryPairs.Remove(key);
return this;
}
public UrlBuilder AlterQuery(string key, Func<string, string> alterMethod, bool removeOnNull = false)
{
string value;
this.QueryPairs.TryGetValue(key, out value);
value = alterMethod(value);
if (removeOnNull && value == null)
{
return this.RemoveQuery(key);
}
else
{
return this.SetQuery(key, value);
}
}
public override string ToString()
{
var path = !string.IsNullOrWhiteSpace(this.Host)
? string.Join("/", this.Host, string.Join("/", this.Paths))
: string.Join("/", this.Paths);
var query = string.Join("&", this.QueryPairs.Select(x => string.Concat(x.Key, "=", HttpUtility.UrlEncode(x.Value))));
return string.Concat(
!string.IsNullOrWhiteSpace(this.Scheme) ? string.Concat(this.Scheme, "://") : null,
path,
!string.IsNullOrWhiteSpace(query) ? string.Concat("?", query) : null);
}
}
}
public static Dictionary<string, string> QueryParametersDictionary()
{
var dictionary = new Dictionary<string, string>();
dictionary.Add("name", "John Doe");
dictionary.Add("address.city", "Seattle");
dictionary.Add("address.state_code", "WA");
dictionary.Add("api_key", "5352345263456345635");
return dictionary;
}
public static string ToQueryString(Dictionary<string, string> nvc)
{
StringBuilder sb = new StringBuilder();
bool first = true;
foreach (KeyValuePair<string, string> pair in nvc)
{
if (!first)
{
sb.Append("&");
}
sb.AppendFormat("{0}={1}", Uri.EscapeDataString(pair.Key), Uri.EscapeDataString(pair.Value));
first = false;
}
return sb.ToString();
}
var queryParams = new SortedList<string,string>(2);
queryParams.Add("abc", "val1");
queryParams.Add("def", "val2");
string requestUri = QueryHelpers.AddQueryString("https://localhost/api", queryParams);
public ActionResult Create()
{
//declaring name value collection object
NameValueCollection collection = new NameValueCollection();
//adding new value to the name value collection object
collection.Add("Id1", "wwe323");
collection.Add("Id2", "454w");
collection.Add("Id3", "tyt5656");
collection.Add("Id4", "343wdsd");
//generating query string
string url = GenerateQueryString(collection);
return View();
}
private string GenerateQueryString(NameValueCollection collection)
{
var querystring = (
from key in collection.AllKeys
from value in collection.GetValues(key)
select string.Format("{0}={1}",
HttpUtility.UrlEncode(key),
HttpUtility.UrlEncode(value))
).ToArray();
return "?" + string.Join("&", querystring);
}