【发布时间】:2019-08-22 09:36:14
【问题描述】:
我正在尝试使用这个 API 并概括 Pagination,因此它可以用于我的任何 API 和模型。我将如何进行?我将现有的代码库放在下面,并希望适用于所有 api 及其 getmethods。正在研究修改此功能。如果 Microsoft 已内置功能来支持这一点,我愿意接受任何其他策略。
来自资源(现有代码仅可用于 1 类 API):
https://dejanstojanovic.net/aspnet/2019/january/filtering-and-paging-in-aspnet-core-web-api/
背景:
我们准备了许多 Get API,现在希望为所有 200 多个 API 提供分页支持。 (我后来进入该项目)无需手动更新/重新编码所有内容,是否有一种自动方法可以使用上述资源链接或其他想法为我们的端点客户应用路由/分页到所有 API?寻求过滤所有 API 的方法。
public ActionResult<PagedCollectionResponse<Person>> Get([FromQuery] SampleFilterModel filter)
/api/Persons?Page=2&Limit=3
/api/Inventory?Page=2&Limit=3
/api/Product?Page=2&Limit=3
/api/Product/GetAll/Page=2&Limit=4
/api/Product/GetByProductCategory/7/Page=2&Limit=4
/api/Product/GetByVendorId/2/Page=2&Limit=4
/api/Product/GetByProductLocation/US/CA/Page=2&Limit=4
代码:
namespace Sample.Web.Api.Models
{
public abstract class FilterModelBase:ICloneable
{
public int Page { get; set; }
public int Limit { get; set; }
public FilterModelBase()
{
this.Page = 1;
this.Limit = 100;
}
public abstract object Clone();
}
}
public class SampleFilterModel:FilterModelBase
{
public string Term { get; set; }
public SampleFilterModel():base()
{
this.Limit = 3;
}
public override object Clone()
{
var jsonString = JsonConvert.SerializeObject(this);
return JsonConvert.DeserializeObject(jsonString,this.GetType());
}
}
namespace Sample.Web.Api.Models
{
public class PagedCollectionResponse<T> where T:class
{
public IEnumerable<T> Items { get; set; }
public Uri NextPage { get; set; }
public Uri PreviousPage { get; set; }
}
}
namespace Sample.Web.Api.Models
{
public class Person
{
public String Name { get; set; }
public DateTime DOB { get; set; }
public String Email { get; set; }
}
}
namespace Sample.Web.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class PersonsController : ControllerBase
{
IEnumerable<Person> persons = new List<Person>() {
new Person() { Name = "Nancy Davolio", DOB = DateTime.Parse("1948-12-08"), Email = "nancy.davolio@test.com" },
new Person() { Name = "Andrew Fuller", DOB = DateTime.Parse("1952-02-19"), Email = "andrew.fuller@test.com" },
new Person() { Name = "Janet Leverling", DOB = DateTime.Parse("1963-08-30"), Email = "janet.leverling@test.com" },
new Person() { Name = "Margaret Peacock", DOB = DateTime.Parse("1937-09-19"), Email = "margaret.peacock@test.com" },
new Person() { Name = "Steven Buchanan", DOB = DateTime.Parse("1955-03-04"), Email = "steven.buchanan@test.com" },
new Person() { Name = "Michael Suyama", DOB = DateTime.Parse("1963-07-02"), Email = "michael.suyama@test.com" },
new Person() { Name = "Robert King", DOB = DateTime.Parse("1960-05-29"), Email = "robert.king@test.com" },
new Person() { Name = "Laura Callahan", DOB = DateTime.Parse("1958-01-09"), Email = "laura.callahan@test.com" },
new Person() { Name = "Anne Dodsworth", DOB = DateTime.Parse("1966-01-27"), Email = "anne.dodsworth@test.com" }
};
// GET api/values
[HttpGet]
public ActionResult<PagedCollectionResponse<Person>> Get([FromQuery] SampleFilterModel filter)
{
//Filtering logic
Func<SampleFilterModel, IEnumerable<Person>> filterData = (filterModel) =>
{
return persons.Where(p => p.Name.StartsWith(filterModel.Term ?? String.Empty, StringComparison.InvariantCultureIgnoreCase))
.Skip((filterModel.Page-1) * filter.Limit)
.Take(filterModel.Limit);
};
//Get the data for the current page
var result = new PagedCollectionResponse<Person>();
result.Items = filterData(filter);
//Get next page URL string
SampleFilterModel nextFilter = filter.Clone() as SampleFilterModel;
nextFilter.Page += 1;
String nextUrl = filterData(nextFilter).Count() <= 0 ? null : this.Url.Action("Get", null, nextFilter, Request.Scheme);
//Get previous page URL string
SampleFilterModel previousFilter = filter.Clone() as SampleFilterModel;
previousFilter.Page -= 1;
String previousUrl = previousFilter.Page <= 0 ? null : this.Url.Action("Get", null, previousFilter, Request.Scheme);
result.NextPage = !String.IsNullOrWhiteSpace(nextUrl) ? new Uri(nextUrl) : null;
result.PreviousPage = !String.IsNullOrWhiteSpace(previousUrl) ? new Uri(previousUrl) : null;
return result;
}
}
}
注意:
需要根据资源将其扩展到 API 级别。我们知道它可以在业务存储库方法中完成,但希望对所有控制器 API 进行泛化,如上面的作者。
【问题讨论】:
-
@mjwills 问题被删除,我只是进行了更多分析
标签: c# asp.net-core .net-core pagination asp.net-core-mvc