Closed mr-t-the-beerdrinker closed 9 years ago
HairyOneMan,
Do I understand that you have successfully converted this project to WebAPI2? If so, is the above code all you changed? Seems to me based on what I'm doing that there are some other things that would need changed as well.
You're right, I have a mistake above. You have to implement interface System.Web.Http.ModelBinding.IModelBinder instead of System.Web.Mvc.IModelBinder in MVC version. Bind method has different types of arguments - you will have to update those and update the ResolveNameValueCollection with the code above. Then it should work. In you web api controller, use ModelBinder from System.Web.Http.ModelBinding (not that for MVC). Mapping additional properties works as for MVC version of binder. Hope it will work for you :)
Great. Thanks for the feedback. Got this working mostly. I'm pulling data through the model. What I don't have working as of yet is Global Search, Column Ordering and Column Filtering. Mostly because I'm not clear from the README where the example code should be used.
Now, that may be becuase my client side is pure HTML/JS and not a View. So my question now is, did you get Search/Ordering/Filtering to work and if so, how?
Thanks again.
Yes, I have everything working just fine. How to use it:
in JS, it is important you have server side, valid URL, and if you have some extra paramaters, also method type, for example:
serverSide: true,
ajax: {
url: '/api/applications/paged',
type: 'POST',
data: function (d) {
d.IsAdminView = WWT.model.isAdminView();
}
},
in this case, you have to add [HttpPost] attribute above your action:
[HttpPost]
[Route("api/applications/paged")]
public DataTablesResponse Paged([ModelBinder(typeof(DataTablesWithAdminPropertyWebApiBinder))] DataTablesRequestWithAdminProperty model)
{
and for filtering/ordering, you have to handle those server-side by yourself, for example:
var applications = _unit.Repository<Application>().GetAll() // here you have IQueryable<Application>
var totalRecordCount = applications.Count();
Filter(applications, cmd.DtModel.Columns.GetFilteredColumns(), out applications, cmd.IsAdminView);
var searchRecordCount = applications.Count();
IOrderedQueryable<Application> sortedApplications = null;
Sort(applications, cmd.DtModel.Columns.GetSortedColumns(), out sortedApplications);
if (cmd.DtModel.Length == -1)
{
return sortedApplications == null ? applications.OrderBy(s => s.Id).ToList() : sortedApplications.ToList();
}
else
{
return sortedApplications == null ?
applications.OrderBy(s => s.Id).Skip(cmd.DtModel.Start).Take(cmd.DtModel.Length).ToList() :
sortedApplications.Skip(cmd.DtModel.Start).Take(cmd.DtModel.Length).ToList();
}
and Filter / Sort methods, should look like this:
private void Filter(IQueryable<Application> applications, IEnumerable<Column> filteredColumns, out IQueryable<Application> filtered, bool isAdminView)
{
foreach (var filteredColumn in filteredColumns)
{
switch (filteredColumn.Data.ToLower())
{
case "id":
int iValue = -1;
if( int.TryParse(filteredColumn.Search.Value, out iValue))
{
applications = applications.Where(a => a.Id == iValue);
}
break;
...
private void Sort(IQueryable<Application> applications, IEnumerable<Column> sortedColumns, out IOrderedQueryable<Application> sorted)
{
IOrderedQueryable<Application> sortedApplications = null;
foreach (var sortedColumn in sortedColumns)
{
switch (sortedColumn.Data.ToLower())
{
case "id":
sortedApplications = sortedApplications == null ? applications.CustomSort(sortedColumn.SortDirection, a => a.Id)
: sortedApplications.CustomSort(sortedColumn.SortDirection, a => a.Id);
break;
where custom sort is my extension:
public static class CollectionSortHelper
{
public static IOrderedQueryable<TSource> CustomSort<TSource, TKey>(this IQueryable<TSource> items, Column.OrderDirection direction, Expression<Func<TSource, TKey>> keySelector)
{
if (direction == Column.OrderDirection.Ascendant)
return items.OrderBy(keySelector);
return items.OrderByDescending(keySelector);
}
public static IOrderedQueryable<TSource> CustomSort<TSource, TKey>(this IOrderedQueryable<TSource> items, Column.OrderDirection direction, Expression<Func<TSource, TKey>> keySelector)
{
if (direction == Column.OrderDirection.Ascendant)
return items.ThenBy(keySelector);
return items.ThenByDescending(keySelector);
}
}
hope, this will help you somehow :)
Hello HairyOneMan!
I don't understand what is the object DataTablesWithAdminPropertyWebApiBinder… Could you explain more ?
Thanks a lot !
Hello,
it's just extended web api binder with additional property (admin flag is posted from datatables request) . Check the custom parameters section on readme of this project.
Today's commit just implemented WebApi2 support. NuGet packages are available now.
First thing first: Great Work :)
I've just wanted to ask, if you'll implement WebApi2 Model Binder (It has to be System.Web.Http.ModelBinding.IModelBinder instead of System.Web.Mvc.IModelBinder). I think it's quite quick as i'm lokoing into the code. Anyway, thx for this.
EDIT:
for me, it was enough to implement the System.Web.Http.ModelBinding with your methods, updating just the ResolveNameValueCollection to this: