title: How to implement search filter in ASP.NET Core Web API
body: <p>In my ASP.NET Core-6 Web API, I have these two models:</p>
  <pre><code>public class Department
  {
      public int Id { get; set; }
      public string DepartmentName { get; set; }
  }
  
  public class Employee
  {
      public int Id { get; set; }
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public string StaffNumber { get; set; }
  
      public int DepartmentId { get; set; }
      public Department Department { get; set; }
  }
  </code></pre>
  <p>In order to be able to do pagination, I have these classes:</p>
  <pre><code>public class Result
  {
      internal Result(bool succeeded, IEnumerable&lt;string&gt; errors)
      {
          Succeeded = succeeded;
          Errors = errors.ToArray();
      }
  
      public bool Succeeded { get; set; }
      public string[] Errors { get; set; }
  
      public static Result Success()
      {
          return new Result(true, new string[] { });
      }
  
      public static Result Failure(IEnumerable&lt;string&gt; errors)
      {
          return new Result(false, errors);
      }
  }
  
  public class PaginatedList&lt;T&gt;
  {
      public List&lt;T&gt; Items { get; }
      public int PageIndex { get; }
      public int TotalPages { get; }
      public int TotalCount { get; }
  
      public PaginatedList(List&lt;T&gt; items, int count, int pageIndex, int pageSize)
      {
          PageIndex = pageIndex;
          TotalPages = (int)Math.Ceiling(count / (double)pageSize);
          TotalCount = count;
          Items = items;
      }
  
      public bool HasPreviousPage =&gt; PageIndex &gt; 1;
      public bool HasNextPage =&gt; PageIndex &lt; TotalPages;
  
      public static async Task&lt;PaginatedList&lt;T&gt;&gt; CreateAsync(IQueryable&lt;T&gt; source, int pageIndex, int pageSize, CancellationToken cancellationToken)
      {
          var count = await source.CountAsync(cancellationToken);
          var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(cancellationToken);
          return new PaginatedList&lt;T&gt;(items, count, pageIndex, pageSize);
      }
  }
  </code></pre>
  <p>I am using Entity Framework, and this is the final code:</p>
  <pre><code>public class GetAllEmployeesWithPaginationQuery : IRequestWrapper&lt;PaginatedList&lt;EmployeeDto&gt;&gt;
  {
      public int DepartmentId { get; set; }
      public int PageNumber { get; set; } = 1;
      public int PageSize { get; set; } = 10;
  }
  
  public class GetAllEmployeesWithPaginationQueryHandler : IRequestHandlerWrapper&lt;GetAllEmployeesWithPaginationQuery, PaginatedList&lt;EmployeeDto&gt;&gt;
  {
      private readonly IApplicationDbContext _context;
      private readonly IMapper _mapper;
  
      public GetAllEmployeesWithPaginationQueryHandler(IApplicationDbContext context, IMapper mapper)
      {
          _context = context;
          _mapper = mapper;
      }
  
      public async Task&lt;ServiceResult&lt;PaginatedList&lt;EmployeeDto&gt;&gt;&gt; Handle(GetAllEmployeesWithPaginationQuery request, CancellationToken cancellationToken)
      {
          PaginatedList&lt;EmployeeDto&gt; list = await _context.Employees
              .Where(x =&gt; x.DepartmentId == request.DepartmentId)
              .OrderBy(o =&gt; o.Name)
              .ProjectToType&lt;EmployeeDto&gt;(_mapper.Config)
              .PaginatedListAsync(request.PageNumber, request.PageSize, cancellationToken);
  
          return list.Items.Any() ? ServiceResult.Success(list) : ServiceResult.Failed&lt;PaginatedList&lt;EmployeeDto&gt;&gt;(ServiceError.NotFound);
      }
  }
  </code></pre>
  <p>I have successfully done the pagination, but needs to do the sorting and search filter using the following fields: FirstName, LastName, StaffNumber and DepartmentName.</p>
  <p>How do I achieve this?</p>
  <p>Thank you.</p>