我想根據Ahmad Mageed的工作向大家分享我的想法。 (這是一個很好的開始。)我需要相同的功能,但我需要它能夠在索引鏈中接受更多的深度。
這使您能夠根據需要讀取儘可能多的子索引,而無需對其進行硬編碼,以在2或3級深度停止。因此,通過此更新,您可以閱讀這樣的查詢字符串......
columns[0][data]=0&columns[0][name]=&columns[0][searchable]=true
&columns[0][orderable]=true&columns[0][search][value]=
&columns[0][search][regex]=false&columns[1][data]=1
&columns[1][name]=&columns[1][searchable]=true
&columns[1][orderable]=true&columns[1][search][value]=
&columns[1][search][regex]=false&columns[2][data]=2
...
&order[0][column]=0&order[0][dir]=asc&start=0&length=10&search[value]=&search[regex]=false
這是我更新後的那部分代碼版本。
public IDictionary ConvertQueryString(string sQry)
{
string pattern = @"(?<Prop>[^[]+)(?:\[(?<Key>[^]]+)\])*=(?<Value>.*)";
// The brackets seem to be encoded as %5B and %5D
var qry = HttpUtility.UrlDecode(sQry);
var re = new Regex(pattern);
var dict = qry.Split(new[] { "?", "&" }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => re.Match(s)).Where(g => g.Success)
.GroupBy(m => m.Groups["Prop"].Value)
.ToDictionary<IGrouping<string, Match>, string, object>(
g => g.Key,
g => GetKey(g, 0));
return dict;
}
private object GetKey(IGrouping<string, Match> grouping, int level)
{
var count = grouping.FirstOrDefault().Groups["Key"].Captures.Count;
// If the level is equal to the captures, then we are at the end of the indexes
if (count == level)
{
var gValue = grouping.Where(gr => gr.Success).FirstOrDefault();
var value = gValue.Groups["Value"].Value;
return value;
}
else
{
return grouping.Where(gr => gr.Success)
.GroupBy(m => m.Groups["Key"].Captures[level].Value)
.ToDictionary<IGrouping<string, Match>, string, object>(
a => a.Key,
a => GetKey(a, level + 1));
}
}
我想進一步建立一個嵌套的字典對象,我想實際上建立基於傳遞的字符串的對象。我需要這個用於新版本的jQuery DataTables,它實際上是產生上面那個令人討厭的查詢字符串的東西。這是一個快速寫,所以它有點粗糙,可能有點容易出錯,因爲我還沒有時間來鞏固它。
// Call it like so.
MyClass object = new MyClass();
WalkDictionary(dict, object);
// At this point the object will be filled out for you.
public class MyClass
{
public List<cColumns> columns { get; set; }
public cSearch search { get; set; }
}
public class cColumns
{
public int? data { get; set; }
public string name { get; set; }
public bool? searchable { get; set; }
public bool? orderable { get; set; }
public cSearch search { get; set; }
}
public class cSearch
{
public string value { get; set; }
public bool? regex { get; set; }
}
我只把我需要的基本類型。所以,如果你需要/想要更多,那麼你將不得不添加它們。
private void WalkDictionary(IDictionary dict, object obj)
{
foreach (string key in dict.Keys)
{
Type t = obj.GetType();
if (t.IsGenericType
&& typeof(List<>) == t.GetGenericTypeDefinition())
{
Type[] typeParameters = t.GetGenericArguments();
foreach (DictionaryEntry item in dict)
{
var lstPropObj = Activator.CreateInstance(typeParameters[0]);
WalkDictionary((IDictionary)item.Value, lstPropObj);
((IList)obj).Add(lstPropObj);
}
return;
}
PropertyInfo prop = obj.GetType().GetProperty(key);
if (prop == null)
continue;
if (dict[key] is IDictionary)
{
//Walk
var objProp = prop.GetValue(obj);
if (objProp == null)
objProp = Activator.CreateInstance(prop.PropertyType);
WalkDictionary(dict[key] as IDictionary, objProp);
prop.SetValue(obj, objProp);
}
else if (prop.PropertyType.IsAssignableFrom(typeof(int)))
{
int val = Convert.ToInt32(dict[key]);
prop.SetValue(obj, val);
}
else if (prop.PropertyType.IsAssignableFrom(typeof(bool)))
{
bool val = Convert.ToBoolean(dict[key]);
prop.SetValue(obj, val);
}
else if (prop.PropertyType.IsAssignableFrom(typeof(string)))
{
string val = Convert.ToString(dict[key]);
prop.SetValue(obj, val);
}
}
}
你能在一個url中顯示這個例子,這樣你就可以發佈一個替代解決方案..? – MethodMan
類似於http://example.com/api/objects?where [id] = 4&orderby [id] = asc'的網址? –
您可以擴展您期望如何訪問最終結果中的參數嗎?一個關鍵是「在哪裏(專欄)」還是僅僅是「專欄」?另外,無論哪種情況,預期值是多少? –