当前位置: 首页 > news >正文

企业展示型电商网站模板自贡彩灯制作公司

企业展示型电商网站模板,自贡彩灯制作公司,网站制作的一般步骤是什么,上海高端室内设计译者荐语#xff1a;如何在RESTFul APIs中进行集合结果分页#xff1f;还是用客户端来拼接链接地址么#xff1f;原文来自互联网#xff0c;由长沙DotNET技术社区【邹溪源】翻译。如译文侵犯您的版权#xff0c;请联系小编#xff0c;小编将在24小时内删除。在ASP.NET Co… 译者荐语如何在RESTFul APIs中进行集合结果分页还是用客户端来拼接链接地址么原文来自互联网由长沙DotNET技术社区【邹溪源】翻译。如译文侵犯您的版权请联系小编小编将在24小时内删除。在ASP.NET Core WebApi项目中分页响应数据REST API的分页响应和通过REST API端点筛选返回的数据它们经常一起出现同样重要。就像过滤一样分页会限制从端点返回的数据量从而节省了客户端和服务器端资源。想象一下如果你想返回一个客户的数据但是却返回了所有客户的数据或者你返回了所有的分页数据而你搜索的数据实际上就在前几条记录中。这将仅导致服务器上处理能力和网络带宽的浪费也给客户端的实现带来了不必要的复杂度。有许多技术可以解决这两个问题例如OData[1]或 GraphQL[2]。但是也可以仅使用依赖于过滤和分页API数据的定制解决方案来解决这些问题。为什么要考虑使用定制解决方案而不是现有技术原因很简单因为它可以避免您的团队浪费时间学习新技术而他们已经可以在没有新技术的情况下解决这些问题。而且这些技术将强加于客户端的适应能力并限制它们的相应客户端的使用。依赖于过滤和分页技术也不是没有复杂性。有时这些简单的方法会变得非常复杂最终会成为消费者/客户的一个问题。我将提到REST API设计中自定义筛选和分页的一些支柱特别是在使用.NET Core WEB API在REST服务中实现筛选和分页时。使过滤器易于扩展我在WEB API项目中实现自定义筛选和分页时发现的常见错误之一是将值作为单独的参数传递给MVC Controller Action方法。且别说他是不是易于扩展这样做使得方法签名变得更加复杂并且有向端点添加更多过滤选项的趋势从而变得更加复杂。 [HttpGet] # public IActionResult Get(String term, int page, int limit) # { # //Handle filtering and paging # } # 假设一段时间后您必须扩展端点以接收DateTime和Boolean参数这些参数将参与过滤。方法签名将更改并变为 [HttpGet] # public IActionResult Get(String term, DateTime minDate, Boolean includeInactive, int page, int limit) # { # //Handle filtering and paging # } # 您已经看到一次更新后您的方法签名变得更加复杂而且为了提高阅读这段代码你还得将其分成两行显示。除非您有版本控制否则将很难与现有端点使用者保持一致而且由于开发者不知道增加了新的参数而由于MVC不知道如何路由请求MVC将不会匹配方法签名只会自动给出404响应。这意味着您必须将新的参数设置为可选参数并将其移动到参数列表的末尾。 [HttpGet] # public IActionResult Get(String term, int page, int limit, DateTime? minDate null, Boolean includeInactivefalse) # { # //Handle filtering and paging # } # 现在参数分散在签名中使方法签名具有混合过滤和分页参数没有逻辑分组或顺序因为除了方法签名中参数列表的末尾您不能拥有其他可选参数。当您意识到必须将这些更改应用到不止一种方法时复杂性就会大大增加。您可能必须同时对多个端点进行更改这不仅使一种方法变得困难而且几乎使整个应用程序外观都难以维护。我认为我们已经提出了足够多的观点可以得出结论对过滤方法使用多个参数是一个坏主意。更好的方法是使用模型并将所有参数作为POCO类的属性。尽管方法仍然是HTTP GET但是MVC可以通过使用模型的[FromQuery]关键字从查询字符串中为您绑定模型。 public class FilterModel # { # public String Term { get; set; } # public DateTime MinDate { get; set; } # public Boolean IncludeInactive { get; set; } # public int Page { get; set; } # public int Limit { get; set; } # } # # [HttpGet] # public IActionResult Get([FromQuery] FilterModel filter) # { # //Handle filtering and paging # } # 现在扩展过滤器是单个类的责任如果您的过滤器在整个项目中是通用的或者它具有公共属性例如页码和页面大小/限制则可以将其带到基类并且如果需要扩展跨多个Actions甚至跨多个Controller的过滤器模型您只需扩展基本模型过滤器类即可。您仍然必须在过滤逻辑中处理新参数但是方法签名将保持不变而无需扩展它。不要让客户端为您分担工作我看到的许多自定义实现都让客户端形成查询字符串以获取下一页。我认为这不是正确的方法。我看到的并且我真的很喜欢的一种实现[3]是ZenDesk API[4]使用的这种。除了实体集合以外响应还包括结果下一页和上一页的URL。样本响应将是这样的{ # persons:[ # { # name: John Smith, # dob: 1984-10-31, # email: johnsmith.test.com # }, # ... # ], # nextPage: http://localhost:5000/api/persons?nameJohnpage2limit100, # previousPage: null # } # 这样您的客户就不必确定下一个页面URL是什么并且在采用当今的现代无限滚动方式的大多数UI实现包括Web和移动上这种方法非常理想因为每个页面滚动到底部都是一种新方法HTTP GET到下一页URL。在WEB API中看起来像这样 public class FilterModel # { # public String Term { get; set; } # public DateTime MinDate { get; set; } # public Boolean IncludeInactive { get; set; } # public int Page { get; set; } # public int Limit { get; set; } # } # # public class PagedCollectionResponseT where T : class # { # public IEnumerableT Items { get; set; } # public Uri NextPage { get; set; } # public Uri PreviousPage { get; set; } # } # # public class Person # { # public String Name { get; set; } # public DateTime DOB { get; set; } # public String Email { get; set; } # } # # [HttpGet] # public ActionResultPagedCollectionResponsePerson Get([FromQuery] FilterModel filter) # { # //Handle filtering and paging # } # 这只是过滤器动作签名的外观的浅层结构。接下来我将用一段简单的代码解释如何在ASP.NET Core WEB API示例控制器中实现这种方法。过滤和分页的简单示例为了向您展示如何使用页面指针URL来实现上述分页方法我将使用一个简单的控制器和字符串的静态集合。理想情况下您将查询存储库中的数据但是为了使事情保持简单并专注于生成所描述的响应结构我将坚持简单的字符串集合。在我们跳到逻辑之前第一件事就是创建模型。由于我们项目中的所有过滤器都会接收页面和限制值因此有必要将其设为抽象类以便任何具有页面调度的过滤器都可以继承它。 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(); } } 我们有一个默认的构造函数它将页面大小Limit属性设置为100这意味着默认情况下任何过滤器模型都将分页显示100个项目的集合中的值。我们还实现了ICloneable接口但是实现保留为抽象以允许继承的类处理克隆逻辑因为它可能涉及继承的POCO类的其他属性。当我们开始实现分页逻辑时您将明白为什么我们需要涉及ICloneable接口。现在让我们通过继承FilterModelBase抽象类来实现过滤器 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()); } } 除了Page和Limit属性之外我还添加了一个附加属性Term该属性应用于过滤我们的字符串集合。我还希望在构造函数中将新页面大小设置为3而不是在基类构造函数中分配的默认页面大小设置为100这是因为希望查看少量数据集的分页。Clone方法表示过滤器模型实例的深层副本使用Newtonsoft.Json[5]包通过简单的序列化/反序列化即可完成。这样我们涵盖了Action方法的输入但是现在我们需要注意输出。为了使响应通用我将使用相同的结构模型但是将根据控制器的需要更改集合的类型。为此我使用了通用类型来声明输出模型以便我们可以在多个Controller Action方法中重用它以返回不同类型的集合元素。 namespace Sample.Web.Api.Models { public class PagedCollectionResponseT where T:class { public IEnumerableT 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; } } } 现在我们准备写下我们的页面处理。正如我提到的我将使用Person类实例的集合并且在此演示中我将它们声明为在Controller构造中启动的集合。 namespace Sample.Web.Api.Controllers { [Route(api/[controller])] [ApiController] public class PersonsController : ControllerBase { IEnumerablePerson persons new ListPerson() { new Person() { Name Nancy Davolio, DOB DateTime.Parse(1948-12-08), Email nancy.davoliotest.com }, new Person() { Name Andrew Fuller, DOB DateTime.Parse(1952-02-19), Email andrew.fullertest.com }, new Person() { Name Janet Leverling, DOB DateTime.Parse(1963-08-30), Email janet.leverlingtest.com }, new Person() { Name Margaret Peacock, DOB DateTime.Parse(1937-09-19), Email margaret.peacocktest.com }, new Person() { Name Steven Buchanan, DOB DateTime.Parse(1955-03-04), Email steven.buchanantest.com }, new Person() { Name Michael Suyama, DOB DateTime.Parse(1963-07-02), Email michael.suyamatest.com }, new Person() { Name Robert King, DOB DateTime.Parse(1960-05-29), Email robert.kingtest.com }, new Person() { Name Laura Callahan, DOB DateTime.Parse(1958-01-09), Email laura.callahantest.com }, new Person() { Name Anne Dodsworth, DOB DateTime.Parse(1966-01-27), Email anne.dodsworthtest.com } }; // GET api/values [HttpGet] public ActionResultPagedCollectionResponsePerson Get([FromQuery] SampleFilterModel filter) { //Filtering logic FuncSampleFilterModel, IEnumerablePerson 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 PagedCollectionResponsePerson(); 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; } } } 该示例代码非常原始它不是生产代码它需要一些处理才能在多个控制器中重复使用但它的目的是在简单数据收集的小样本上生成所需的输出数据结构和分页逻辑。让我们一步一步地分析该方法的逻辑块•过滤逻辑 从源数据集合返回项目集合的Simple Func会根据传递的过滤器模型来获取一批对象。此实现很大程度上取决于您的过滤逻辑和您要应用过滤器的数据。Func主体特定于Action方法。•获取当前页面的数据 上述Func实现的简单用法 。将逻辑放在Func中的原因是供以后重用以确定下一页和上一页URL。•获取下一页URL字符串 在这里我们正在创建具有更新的页码的新模型。还记得我们使用ICloneable作为过滤器POCO吗现在我们将使用它来创建深层副本并更新模型的页码以便我们可以生成下一页的URL。在生成下一页的URL之前我们需要知道下一页号是否返回任何元素。我们不想在下一页将客户端发送到空集合响应因为我们希望客户端仅依赖NextPage和PreviousPage URL属性。•获取上一页URL字符串 与获取NextPage URL非常相似但逻辑上略有不同。我们不需要将结果集集合计为下一页URL。我们只需要检查页码是否为1这意味着没有更多的页面PreviousPage URL为空值。我们几乎涵盖了所有内容因此让我们看一下它在POSTMAN中的实际工作方式。图片在具有默认页面参数的初始请求中我们可以看到结果集合中有3个人我们的NextPage URL指向页面号增加1的URL而PreviousPage URL为null因为我们在首页上并且没有之前的页面。如果我们遵循NextPage URL并在POSTMAN中对其执行HTTP GET我们将得到以下响应。图片现在您可以看到我们同时具有NextPage URL和PreviousPage URL。如果您注意到示例数据集合中有9个元素这意味着对NextPage URL的请求应在结果集合中再给我们3个元素。图片我们的最后一页在结果集中返回3个人但是您可以注意到NextPage URL为空。这是因为页数4的计数将在响应中不返回任何元素并且我们正在通知使用者没有更多数据要返回。我在一个简单的数据收集上演示了此WEB API响应分页但实际情况将涉及数据过滤和查询数据存储库。我希望 不久的将来我将能够通过使用存储库模式和可重复使用的逻辑可以应用于多个控制器和操作而无需任何代码重复的展示以更加精细的实现编写更详细的文本。References[1] OData: https://www.odata.org/[2] GraphQL: https://graphql.org/[3] 实现: https://developer.zendesk.com/rest_api[4] ZenDesk API: https://developer.zendesk.com/rest_api[5] Newtonsoft.Json: https://www.newtonsoft.com/
http://wiki.neutronadmin.com/news/55061/

相关文章:

  • 网站后台如何添加关键词什么是营销网站建设
  • 专门做汽车配件的外贸网站所有爱做网站
  • 烟台专业网站建设公司宁波优化关键词首页排名
  • 如何让自己的网站快速被百度收录温州高端模板建站
  • 网站商品图片怎么做天津移动网站建设
  • 招聘网站有哪些平台在网站上保存网址怎么做
  • 全球十大网站排名织梦 做网站 知乎
  • 语音app开发公司北京数据优化公司
  • 做代码的网站淘客做网站运营
  • 自学做网站的书wordpress 用户名
  • 网站建设要注意哪些wordpress按分类搜索
  • 太原seo网站优化建设维护网站 未签订合同
  • 甘肃兰州网站建设音乐网站建设方案书模板
  • 网页设计与网站建设主要内容网络营销推广活动方案
  • 长春seo网站优化佛山高端网页制作
  • 吉林市做网站的科技html5网站后台页面设计
  • 网站显示备案号seo站外推广
  • ps制作博客网站界面外贸网站平台是不是很难做
  • 中建招聘网站wordpress如何加表情
  • 做外汇看新闻在什么网站看wordpress 摘要函数
  • 山东建设局网站电工网站 网页区别是什么
  • 汽车 营销 网站建设多语言网站思路
  • 专业的美容网站建设公关咨询公司
  • php网站建设 关键技术沈阳男科三甲医院排行榜
  • 一个人做的网站做什么好外贸型网站建设方法
  • 前端做网站难吗专业的定制型网站建设
  • 网站推广渠道制作简易网站
  • 中国工商银行官网网站wordpress 手机维修
  • 江苏省泰州市建设局官方网站邯郸网站制作外包
  • 网站建设需要什么流程图中国石油天然气第七建设公司网站