/// <summary> /// Creates new <see cref="DataTablesRequest{T}"/> from <see cref="NameValueCollection"/> instance. /// </summary> /// <param name="query"></param> public DataTablesRequest(NameValueCollection query) { if (query == null) { throw new ArgumentNullException("Datatables query parameters collection is null."); } if (!query.HasKeys()) { throw new ArgumentException("Datatables query has no keys."); } OriginalRequest = new NameValueCollection(query); int start = Int32.TryParse(query["start"], out start) ? start : 0; int length = Int32.TryParse(query["length"], out length) ? length : 15; int draw = Int32.TryParse(query["draw"], out draw) ? draw : 0; string globalSearch = query["search[value]"]; bool searchRegex = Boolean.TryParse(query["search[regex]"], out searchRegex) ? searchRegex : false; int pageNumber = start / length + 1; GlobalSearchValue = globalSearch; GlobalSearchRegex = searchRegex; PageNumber = pageNumber; PageSize = length; Draw = draw; // extract columns info string columnPattern = "columns\\[(\\d+)\\]\\[data\\]"; var columnKeys = query.AllKeys.Where(k => k != null && Regex.IsMatch(k, columnPattern)); foreach (var key in columnKeys) { var colIndex = Regex.Match(key, columnPattern).Groups[1].Value; bool orderable = Boolean.TryParse(query[$"columns[{colIndex}][orderable]"], out orderable) ? orderable : true; bool searchable = Boolean.TryParse(query[$"columns[{colIndex}][searchable]"], out searchable) ? searchable : true; bool colSearchRegex = Boolean.TryParse(query["search[regex]"], out colSearchRegex) ? colSearchRegex : false; bool colCISearch = Boolean.TryParse(query[$"columns[{colIndex}][cisearch]"], out colCISearch) ? colCISearch : false; bool colCIOrder = Boolean.TryParse(query[$"columns[{colIndex}][ciorder]"], out colCIOrder) ? colCIOrder : false; string data = query[$"columns[{colIndex}][data]"]; string name = query[$"columns[{colIndex}][name]"]; string searchValue = query[$"columns[{colIndex}][search][value]"]; string propertyName = null; PropertyInfo propertyInfo = null; Type type = typeof(T); // take property name from `data` if (colIndex.ToString() != data) { propertyInfo = GetPropertyByName(type, data); if (propertyInfo != null) { propertyName = data; } else { throw new NoPropertyByNameException($"Could not find a property called \"{data}\" on type \"{type}\". Make sure you have specified correct value of \"columnDefs.data\" parameter in datatables options."); } } // take property name from `name` if (propertyInfo == null && !string.IsNullOrWhiteSpace(name)) { propertyInfo = GetPropertyByName(type, name); if (propertyInfo != null) { propertyName = name; } else { throw new NoPropertyByNameException($"Could not find a property called \"{name}\" on type \"{type}\". Make sure you have specified correct value of \"columnDefs.name\" parameter in datatables options."); } } if (propertyName == null) { throw new NoPropertyByNameException($"Unable to associate datatables column \"{colIndex}\" with model type \"{typeof(T)}\". There are no matching public property found. Make sure you specified valid identifiers for \"columnDefs.data\" and/or \"columnDefs.name\" parameters in datatables options for the column \"{colIndex}\"."); } var column = new DataTablesColumn <T>() { Index = Int32.Parse(colIndex), PropertyName = propertyName, SearchValue = searchValue, SearchRegex = colSearchRegex, IsSearchable = searchable, IsOrderable = orderable, SearchCaseInsensitive = colCISearch, OrderingCaseInsensitive = colCIOrder }; Columns.Add(column); } // extract sorting info string orderPattern = "order\\[(\\d)\\]\\[column\\]"; var orderKeys = query.AllKeys.Where(k => k != null && Regex.IsMatch(k, orderPattern)); foreach (var key in orderKeys) { var index = Regex.Match(key, orderPattern).Groups[1].Value; int columnIndex = 0; int sortingIndex = 0; if (Int32.TryParse(index, out sortingIndex) && Int32.TryParse(query[$"order[{index}][column]"], out columnIndex)) { var column = Columns.FirstOrDefault(c => c.Index == columnIndex); if (column != null) { column.OrderingIndex = sortingIndex; column.OrderingDirection = query[$"order[{index}][dir]"] == "desc" ? ListSortDirection.Descending : ListSortDirection.Ascending; } } } }
/// <summary> /// Creates new <see cref="DataTablesRequest{T}"/> from <see cref="NameValueCollection"/> instance. /// </summary> /// <param name="query"></param> public DataTablesRequest(NameValueCollection query) { if (query == null) { throw new ArgumentNullException("Datatables query parameters collection is null."); } if (!query.HasKeys()) { throw new ArgumentException("Datatables query has no keys."); } mOrginalRequest = new NameValueCollection(query); #if TRACE Trace.WriteLine($"DataTables.Queryable incoming request parameters:"); query.AllKeys.ToList().ForEach(k => Trace.WriteLine($"{k} = {query[k]}")); #endif int start = Int32.TryParse(query["start"], out start) ? start : 0; int length = Int32.TryParse(query["length"], out length) ? length : 15; string sortFieldColumnIndex = query["order[0][column]"]; string globalSearch = query["search[value]"]; bool searchRegex = Boolean.TryParse(query["search[regex]"], out searchRegex) ? searchRegex : false; int pageNumber = start / length + 1; GlobalSearchValue = globalSearch; GlobalSearchRegex = searchRegex; PageNumber = pageNumber; PageSize = length; // extract columns info string columnPattern = "columns\\[(\\d+)\\]\\[data\\]"; var columnKeys = query.AllKeys.Where(k => k != null && Regex.IsMatch(k, columnPattern)); foreach (var key in columnKeys) { var colIndex = Regex.Match(key, columnPattern).Groups[1].Value; bool orderable = Boolean.TryParse(query[$"columns[{colIndex}][orderable]"], out orderable) ? orderable : true; bool searchable = Boolean.TryParse(query[$"columns[{colIndex}][searchable]"], out searchable) ? searchable : true; bool colSearchRegex = Boolean.TryParse(query["search[regex]"], out colSearchRegex) ? colSearchRegex : false; bool colCISearch = Boolean.TryParse(query[$"columns[{colIndex}][cisearch]"], out colCISearch) ? colCISearch : false; bool colCIOrder = Boolean.TryParse(query[$"columns[{colIndex}][ciorder]"], out colCIOrder) ? colCIOrder : false; string data = query[$"columns[{colIndex}][data]"]; string name = query[$"columns[{colIndex}][name]"]; string searchValue = query[$"columns[{colIndex}][search][value]"]; string propertyName = null; PropertyInfo propertyInfo = null; Type type = typeof(T); propertyInfo = GetPropertyByName(type, data); if (propertyInfo != null) { propertyName = data; } else { propertyInfo = GetPropertyByName(type, name); if (propertyInfo != null) { propertyName = name; } } if (propertyName == null) { throw new ArgumentException($"Unable to associate datatables column \"{colIndex}\" with model type \"{typeof(T)}\". There are no matching public property found. Make sure you specified valid identifiers for \"data\" and/or \"name\" parameters in datatables options."); } var column = new DataTablesColumn <T>() { Index = Int32.Parse(colIndex), PropertyName = propertyName, SearchValue = searchValue, SearchRegex = colSearchRegex, IsSearchable = searchable, IsOrderable = orderable, SearchCaseInsensitive = colCISearch, OrderingCaseInsensitive = colCIOrder }; Columns.Add(column); } // extract sorting info string orderPattern = "order\\[(\\d)\\]\\[column\\]"; var orderKeys = query.AllKeys.Where(k => k != null && Regex.IsMatch(k, orderPattern)); foreach (var key in orderKeys) { var index = Regex.Match(key, orderPattern).Groups[1].Value; int columnIndex = 0; int sortingIndex = 0; if (Int32.TryParse(index, out sortingIndex) && Int32.TryParse(query[$"order[{index}][column]"], out columnIndex)) { var column = Columns.FirstOrDefault(c => c.Index == columnIndex); if (column != null) { column.OrderingIndex = sortingIndex; column.OrderingDirection = query[$"order[{index}][dir]"] == "desc" ? ListSortDirection.Descending : ListSortDirection.Ascending; } } } }