current=1&rowCount=10&sort[sender]=asc&searchPhrase=&id=b0df282a-0d67-40e5-8558-c9e93b7befed
[AttributeUsage(AttributeTargets.Property,Inherited = true)] public class RequestBodyField:Attribute { public string Field; public RequestBodyField(string field) { this.Field = field; } }
public class EmployeesRequestBody { [RequestBodyField("current")] public int CurrentPage { get; set; } [RequestBodyField("rowcount")] public int RowCount { get; set; } [RequestBodyField("searchPhrase")] public string SearchPhrase { get; set; } [RequestBodyField("sort")] public NameValueCollection SortDictionary { get; set; } }
public T GetFromQueryString<T>() where T : new() { var obj = new T(); var queryString = HttpContext.Current.Request.QueryString; var queries = HttpUtility.ParseQueryString(queryString.ToString()); var properties = typeof(T).GetProperties(); foreach (var property in properties) { foreach (Attribute attribute in property.GetCustomAttributes(true)) { var requestBodyField = attribute as RequestBodyField; if (requestBodyField == null) continue; //get value of query string var valueAsString = queries[requestBodyField.Field]; var converter = TypeDescriptor.GetConverter(property.PropertyType); var value = converter.ConvertFrom(valueAsString); if (value == null) continue; property.SetValue(obj, value, null); } } return obj; }
HttpContext.Current.Request.QueryString
سپس در مرحلهی بعدی با استفاده از Reflection پراپرتیهایی را که دارای attribute تعریف شده هستند، پیدا میکنیم.
var converter = TypeDescriptor.GetConverter(property.PropertyType); var value = converter.ConvertFrom(valueAsString);
سپس در صورتی که مقدار صحیح دریافت شود و برابر null نباشد، مقدار را در پراپرتی مربوطه جا میدهیم.
نکتهای که در اینجا نیاز به تلاش بیشتر دارد، کلید sort در کوئری استرینگ است. با نگاهی دقیقتر متوجه میشوید که خود کلید دو مقدار دارد که یکی از مقادیرش با کلید ترکیب شده است. این حالت روش ارسال آرایهها با نام کلیدی متفاوت در کوئری استرینگ است. این حالت ارسال باعث میشود که گرید بتواند حالت multi sort را نیز پیاده سازی کند.
پس برای دریافت این نوع مقادیر کمی کد به آن اضافه میکنیم. برای دریافت مقادیر آرایهای کد زیر را به سیستم اضافه میکنیم:
if (valueAsString == null) { var keys = from key in queries.AllKeys where key.StartsWith(requestBodyField.Field) select key; var collection = new NameValueCollection(); foreach (var key in keys) { var openBraketIndex = key.IndexOf("[", StringComparison.Ordinal); var closeBraketIndex = key.IndexOf("]", StringComparison.Ordinal); if (openBraketIndex < 0 || closeBraketIndex < 0) throw new Exception("query string is corrupted."); openBraketIndex++; //get key in [...] var fieldName = key.Substring(openBraketIndex, closeBraketIndex - openBraketIndex); collection.Add(fieldName, queries[key] ); } property.SetValue(obj, collection, null); continue; }
public T GetFromQueryString<T>() where T : new() { var obj = new T(); var properties = typeof(T).GetProperties(); var queryString = HttpContext.Current.Request.QueryString; var queries = HttpUtility.ParseQueryString(queryString.ToString()); foreach (var property in properties) { foreach (Attribute attribute in property.GetCustomAttributes(true)) { var requestBodyField = attribute as RequestBodyField; if (requestBodyField == null) continue; //get value of query string var valueAsString = queries[requestBodyField.Field]; if (valueAsString == null) { var keys = from key in queries.AllKeys where key.StartsWith(requestBodyField.Field) select key; var collection = new NameValueCollection(); foreach (var key in keys) { var openBraketIndex = key.IndexOf("[", StringComparison.Ordinal); var closeBraketIndex = key.IndexOf("]", StringComparison.Ordinal); if (openBraketIndex < 0 || closeBraketIndex < 0) throw new Exception("query string is corrupted."); openBraketIndex++; //get key in [...] var fieldName = key.Substring(openBraketIndex, closeBraketIndex - openBraketIndex); collection.Add(fieldName, queries[key]); } property.SetValue(obj, collection, null); continue; } var converter = TypeDescriptor.GetConverter(property.PropertyType); var value = converter.ConvertFrom(valueAsString); if (value == null) continue; property.SetValue(obj, value, null); } } return obj; }
حال به صورت زیر این متد را صدا میزنیم:
public virtual ActionResult GetEmployees() { var request = new Requests().GetFromQueryString<EmployeesRequestBody>(); }