我想改进我的Web API测试并寻找更好地格式化网址的方法。
var filter = new {
State = new[] {"A", "C"},
MaxAge = 60,
POI = new { Lat = 40, Long = -130 }
};
我打算如何像JQuery.param()函数一样格式化查询字符串?
答案 0 :(得分:3)
There您可以找到一个扩展方法,它可以帮助您将对象转换为查询字符串
public static class UrlHelpers
{
public static string ToQueryString(this object request, string separator = ",")
{
if (request == null)
throw new ArgumentNullException("request");
// Get all properties on the object
var properties = request.GetType().GetProperties()
.Where(x => x.CanRead)
.Where(x => x.GetValue(request, null) != null)
.ToDictionary(x => x.Name, x => x.GetValue(request, null));
// Get names for all IEnumerable properties (excl. string)
var propertyNames = properties
.Where(x => !(x.Value is string) && x.Value is IEnumerable)
.Select(x => x.Key)
.ToList();
// Concat all IEnumerable properties into a comma separated string
foreach (var key in propertyNames)
{
var valueType = properties[key].GetType();
var valueElemType = valueType.IsGenericType
? valueType.GetGenericArguments()[0]
: valueType.GetElementType();
if (valueElemType.IsPrimitive || valueElemType == typeof (string))
{
var enumerable = properties[key] as IEnumerable;
properties[key] = string.Join(separator, enumerable.Cast<object>());
}
}
// Concat all key/value pairs into a string separated by ampersand
return string.Join("&", properties
.Select(x => string.Concat(
Uri.EscapeDataString(x.Key), "=",
Uri.EscapeDataString(x.Value.ToString()))));
}
}
并将其用作string querystring = example.ToQueryString();
答案 1 :(得分:1)
这是我的扩展方法。它支持嵌套。 Javascript对象表示为Dictionary&lt; string,object&gt;和javascript数组为IEnumerable。
public static class ToQueryStringExtension
{
public static string ToQueryString(this Dictionary<string, object> obj)
{
if (obj == null) return "";
string query = "";
bool first = true;
Dictionary<string, List<string>> data = ToQueryStringHelper(obj);
foreach (KeyValuePair<string, List<string>> kvp in data)
{
string keyUrlencoded = UpperCaseUrlEncode(kvp.Key);
foreach (string ele in kvp.Value)
{
if (first) first = false;
else query += "&";
query += keyUrlencoded + ele;
}
}
return query;
}
private static Dictionary<string, List<string>> ToQueryStringHelper(Dictionary<string, object> obj)
{
Dictionary<string, List<string>> data = new Dictionary<string, List<string>>();
foreach (KeyValuePair<string, object> kvp in obj)
{
if (kvp.Value is Dictionary<string, object>)
{
Dictionary<string, List<string>> dataInner = ToQueryStringHelper((Dictionary<string, object>)kvp.Value);
if (dataInner.Count < 1) continue;
data.Add(kvp.Key, new List<string>());
foreach (KeyValuePair<string, List<string>> kvpInner in dataInner)
{
string keyUrlencoded = UpperCaseUrlEncode("[" + kvpInner.Key + "]");
foreach (string ele in kvpInner.Value)
{
data[kvp.Key].Add(keyUrlencoded + ele);
}
}
}
else if ((kvp.Value is IEnumerable) && !(kvp.Value is string))
{
Dictionary<string, object> objInner = new Dictionary<string, object>();
IEnumerable list = (IEnumerable)kvp.Value;
int inx = 0;
foreach (object ele in list)
{
objInner.Add(inx.ToString(), ele);
inx++;
}
Dictionary<string, List<string>> dataInner = ToQueryStringHelper(objInner);
if (dataInner.Count < 1) continue;
data.Add(kvp.Key, new List<string>());
foreach (KeyValuePair<string, List<string>> kvpInner in dataInner)
{
// index key can be removed in peripheral nodes
string keyUrlencoded = null;
if (kvpInner.Value.Count == 1 && kvpInner.Value[0].StartsWith("=")) keyUrlencoded = General.UpperCaseUrlEncode("[]");
else keyUrlencoded = UpperCaseUrlEncode("[" + kvpInner.Key + "]");
foreach (string ele in kvpInner.Value)
{
data[kvp.Key].Add(keyUrlencoded + ele);
}
}
}
else
{
// Optional check if peripheral value type is known.
//Type type = kvp.Value.GetType();
//if (!(kvp.Value is Decimal) && !(kvp.Value is string) && !(type.IsPrimitive)) throw new Exception("Unknown peripheral type.");
if (kvp.Value != null)
{
data.Add(kvp.Key, new List<string>());
data[kvp.Key].Add("=" + UpperCaseUrlEncode(kvp.Value.ToString()));
}
}
}
return data;
}
public static string UpperCaseUrlEncode(string s)
{
char[] temp = HttpUtility.UrlEncode(s).ToCharArray();
for (int i = 0; i < temp.Length - 2; i++)
{
if (temp[i] == '%')
{
temp[i + 1] = char.ToUpper(temp[i + 1]);
temp[i + 2] = char.ToUpper(temp[i + 2]);
}
}
return new string(temp);
}
}