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

深南花园裙楼 网站建设宁波企业建网站报价

深南花园裙楼 网站建设,宁波企业建网站报价,做一普通网站需要多少钱,一站式平台网站开发技术1前言开发接口#xff0c;是给客户端#xff08;Web前端、App#xff09;用的#xff0c;前面说的RESTFul#xff0c;是接口的规范#xff0c;有了统一的接口风格#xff0c;客户端开发人员在访问后端功能的时候能更快找到需要的接口#xff0c;能写出可维护性更高的代…1前言开发接口是给客户端Web前端、App用的前面说的RESTFul是接口的规范有了统一的接口风格客户端开发人员在访问后端功能的时候能更快找到需要的接口能写出可维护性更高的代码。而接口的数据返回格式也是接口规范的重要一环不然一个接口返回JSON一个返回纯字符串客户端对接到数据时一脸懵逼没法处理啊。合格的接口返回值应该包括状态码、提示信息和数据。就像这样{statusCode: 200,successful: true,message: null,data: {} }默认AspNetCore的WebAPI模板是没有特定的返回格式因为这些业务性质的东西需要开发者自己来定义和完成。在前面的文章中可以看到本项目的接口返回值都是 ApiResponse 及其派生类型这就是在StarBlog里定制的统一返回格式。事实上我的其他项目也在用这套接口返回值这已经算是一个 Utilities 性质的组件了。PS今天写这篇文章时我顺手把这个返回值发布了一个nuget包以后在其他项目里使用就不用复制粘贴了~2分析一下在 AspNetCore 里写 WebApi 我们的 Controller 需要继承 ControllerBase 这个类接口 Action 可以设置返回值为 IActionResult 或 ActionResultT 类型然后返回数据的时候可以使用 ControllerBase 封装好的 Ok(), NotFound() 等方法这些方法在返回数据的同时会自动设置响应的HTTP状态码。PS关于 IActionResult 或 ActionResultT 这俩的区别请参考官方文档。本文只提关键的一点ActionResultT返回类型可以让接口在swagger文档中直观看出返回的数据类型。所以我们不仅要封装统一的返回值还要实现类似 Ok(), NotFound(), BadRequest() 的快捷方法。显然当接口返回类型全都是 ApiResponseT 时这样返回的状态码都是200不符合需求。而且有些接口之前已经写好了返回类型是 ListT 这类的我们也要把这些接口的返回值包装起来统一返回格式。要解决这些问题我们得了解一下 AspNetCore 的管道模型。AspNetCore 管道模型最外层是中间件一个请求进来经过一个个中间件到最后一个中间件生成响应再依次经过一个个中间件走出来得到最终响应。image常用的 AspNetCore 项目中间件有这些如下图所示image最后的 Endpoint 就是最终生成响应的中间件。在本项目中Program.cs 配置里的最后一个中间件就是添加了一个处理 MVC 的 Endpointapp.MapControllerRoute(name: default,pattern: {controllerHome}/{actionIndex}/{id?});这个 Endpoint 的结构又是这样的image可以看到有很多 Filter 包围在用户代码的前后。所以得出结论要修改请求的响应我们可以选择写一个中间件处理使用过滤器(Filter)那么来开始写代码吧~3定义ApiResponse首先是这个出现频率很高的 ApiResponse终于要揭晓了~在 StarBlog.Web/ViewModels/Response 命名空间下我创建了三个文件分别是ApiResponse.csApiResponsePaged.cs: 分页响应IApiResponse.cs: 几个相关的接口ApiResponse.cs 中其实是两个类一个 ApiResponseT 另一个 ApiResponse带泛型和不带泛型。PSC#的泛型有点复杂当时搞这东西搞得晕晕的又复习了一些逆变和协变不过最终没有用上。接口代码上代码先是几个接口的代码public interface IApiResponse {public int StatusCode { get; set; }public bool Successful { get; set; }public string? Message { get; set; } }public interface IApiResponseT : IApiResponse {public T? Data { get; set; } }public interface IApiErrorResponse {public Dictionarystring,object ErrorData { get; set; } }保证了所有相关对象都来自 IApiResponse 接口。ApiResponseT接着看 ApiResponseT 的代码。public class ApiResponseT : IApiResponseT {public ApiResponse() {}public ApiResponse(T? data) {Data  data;}public int StatusCode { get; set; }  200;public bool Successful { get; set; }  true;public string? Message { get; set; }public T? Data { get; set; }/// summary/// 实现将 see crefApiResponse/ 隐式转换为 see crefApiResponse{T}//// /summary/// param nameapiResponsesee crefApiResponse//parampublic static implicit operator ApiResponseT(ApiResponse apiResponse) {return new ApiResponseT {StatusCode  apiResponse.StatusCode,Successful  apiResponse.Successful,Message  apiResponse.Message};} }这里使用运算符重载实现了 ApiResponse 到 ApiResponseT 的隐式转换。等下就能看出有啥用了~ApiResponse继续看 ApiResponse 代码比较长封装了几个常用的方法在里面会有一些重复代码。这个类实现了俩接口IApiResponse, IApiErrorResponsepublic class ApiResponse : IApiResponse, IApiErrorResponse {public int StatusCode { get; set; }  200;public bool Successful { get; set; }  true;public string? Message { get; set; }public object? Data { get; set; }/// summary/// 可序列化的错误/// para用于保存模型验证失败的错误信息/para/// /summarypublic Dictionarystring,object? ErrorData { get; set; }public ApiResponse() {}public ApiResponse(object data) {Data  data;}public static ApiResponse NoContent(string message  NoContent) {return new ApiResponse {StatusCode  StatusCodes.Status204NoContent,Successful  true, Message  message};}public static ApiResponse Ok(string message  Ok) {return new ApiResponse {StatusCode  StatusCodes.Status200OK,Successful  true, Message  message};}public static ApiResponse Ok(object data, string message  Ok) {return new ApiResponse {StatusCode  StatusCodes.Status200OK,Successful  true, Message  message,Data  data};}public static ApiResponse Unauthorized(string message  Unauthorized) {return new ApiResponse {StatusCode  StatusCodes.Status401Unauthorized,Successful  false, Message  message};}public static ApiResponse NotFound(string message  NotFound) {return new ApiResponse {StatusCode  StatusCodes.Status404NotFound,Successful  false, Message  message};}public static ApiResponse BadRequest(string message  BadRequest) {return new ApiResponse {StatusCode  StatusCodes.Status400BadRequest,Successful  false, Message  message};}public static ApiResponse BadRequest(ModelStateDictionary modelState, string message  ModelState is not valid.) {return new ApiResponse {StatusCode  StatusCodes.Status400BadRequest,Successful  false, Message  message,ErrorData  new SerializableError(modelState)};}public static ApiResponse Error(string message  Error, Exception? exception  null) {object? data  null;if (exception ! null) {data  new {exception.Message,exception.Data};}return new ApiResponse {StatusCode  StatusCodes.Status500InternalServerError,Successful  false,Message  message,Data  data};} }ApiResponsePagedT这个分页是最简单的只是多了个 Pagination 属性而已public class ApiResponsePagedT : ApiResponseListT where T : class {public ApiResponsePaged() {}public ApiResponsePaged(IPagedListT pagedList) {Data  pagedList.ToList();Pagination  pagedList.ToPaginationMetadata();}public PaginationMetadata? Pagination { get; set; } }4类型隐式转换来看这个接口public ApiResponsePost Get(string id) {var post  _postService.GetById(id);return post  null ? ApiResponse.NotFound() : new ApiResponsePost(post); }根据上面的代码可以发现 ApiResponse.NotFound() 返回的是一个 ApiResponse 对象但这接口的返回值明明是 ApiResponsePost 类型呀这不是类型不一致吗不过在 ApiResponseT 中我们定义了一个运算符重载实现了 ApiResponse 类型到 ApiResponseT 的隐式转换所以就完美解决这个问题大大减少了代码量。不然原本是要写成这样的return post  null ? new ApiResponsePost {StatusCode  StatusCodes.Status404NotFound,Successful  false, Message  未找到} : new ApiResponsePost(post);现在只需简简单单的 ApiResponse.NotFound()就跟 AspNetCore 自带的一样妙~5包装返回值除了这些以 ApiResponse 或 ApiResponseT 作为返回类型的接口还有很多其他返回类型的接口比如public ListConfigItem GetAll() {return _service.GetAll(); }还有public async Taskstring Poem() {return await _crawlService.GetPoem(); }这些接口在 AspNetCore 生成响应的时候会把这些返回值归类为 ObjectResult 如果不做处理就会直接序列化成不符合我们返回值规范的格式。这个不行必须对这部分接口的返回格式也统一起来。因为种种原因最终我选择使用过滤器来实现这个功能。关于过滤器的详细用法可以参考官方文档本文就不展开了直接上代码。创建文件 StarBlog.Web/Filters/ResponseWrapperFilter.cspublic class ResponseWrapperFilter : IAsyncResultFilter {public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) {if (context.Result is ObjectResult objectResult) {if (objectResult.Value is IApiResponse apiResponse) {objectResult.StatusCode  apiResponse.StatusCode;context.HttpContext.Response.StatusCode  apiResponse.StatusCode;}else {var statusCode  objectResult.StatusCode ?? context.HttpContext.Response.StatusCode;var wrapperResp  new ApiResponseobject {StatusCode  statusCode,Successful  statusCode is  200 and  400,Data  objectResult.Value,};objectResult.Value  wrapperResp;objectResult.DeclaredType  wrapperResp.GetType();}}await next();} }在代码中进行判断当响应的类型是 ObjectResult 时把这个响应结果拿出来再判断是不是 IApiResponse 类型。前面我们介绍过所有 ApiResponse 都实现了 IApiResponse 这个接口所以可以判断是不是 IApiResponse 类型来确定这个返回结果是否包装过。没包装的话就给包装一下就这么简单。之后在 Program.cs 里注册一下这个过滤器。var mvcBuilder  builder.Services.AddControllersWithViews(options  { options.Filters.AddResponseWrapperFilter(); } );6搞定这样就完事儿啦~最后所有接口可序列化的返回格式就都变成了这样{statusCode: 200,successful: true,message: null,data: {} }强迫症表示舒服了~PS对了返回文件的那类接口除外。7在其他项目中使用这个 ApiRepsonse 我已经发布了nuget包需要在其他项目使用的话可以直接安装 CodeLab.Share 这个包引入 CodeLab.Share.ViewModels.Response 命名空间就完事了~不用每次都复制粘贴这几个类还得改命名空间。PS这个包里不包括过滤器8参考资料https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?viewaspnetcore-7.09系列文章基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目基于.NetCore开发博客项目 StarBlog - (3) 模型设计基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入基于.NetCore开发博客项目 StarBlog - (5) 开始搭建Web项目基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表基于.NetCore开发博客项目 StarBlog - (7) 页面开发之文章详情页面基于.NetCore开发博客项目 StarBlog - (8) 分类层级结构展示基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入基于.NetCore开发博客项目 StarBlog - (10) 图片瀑布流基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能基于.NetCore开发博客项目 StarBlog - (14) 实现主题切换功能基于.NetCore开发博客项目 StarBlog - (15) 生成随机尺寸图片基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)基于.NetCore开发博客项目 StarBlog - (17) 自动下载文章里的外部图片基于.NetCore开发博客项目 StarBlog - (18) 实现本地Typora文章打包上传基于.NetCore开发博客项目 StarBlog - (19) Markdown渲染方案探索基于.NetCore开发博客项目 StarBlog - (20) 图片显示优化基于.NetCore开发博客项目 StarBlog - (21) 开始开发RESTFul接口基于.NetCore开发博客项目 StarBlog - (22) 开发博客文章相关接口基于.NetCore开发博客项目 StarBlog - (23) 文章列表接口分页、过滤、搜索、排序基于.NetCore开发博客项目 StarBlog - (24) 统一接口数据返回格式
http://www.huolong8.cn/news/272352/

相关文章:

  • 免费建立网站软件对网站建设 意见和建议
  • 网站托管服务器模板网站什么意思
  • 网站建设新闻发布wordpress阅读器
  • 东营+网站建设做网站的技术支持
  • 中国小康建设网 官方网站网站建设如何定价
  • 网站没有备案号网站建设 外文文献
  • 一个虚拟机怎么做两个网站高坪网站建设
  • 中兴建设 基金管理有限公司网站山西seo顾问
  • 织梦cms做多语言的网站大公司网站色彩设计
  • 网站开发技术html5建网站的经历
  • 做网站都需要做什么中山好的网站建设公司
  • 济南做html5网站建网站要学什么
  • 温州高端品牌网站建设公司部门
  • 自己做网站系统破解wordpress可见
  • 2012年网站设计方法培训机构需要什么资质
  • 夸克破解可看禁用网站百度百科网站开发
  • 平凉市建设局门户网站做相册哪个网站好用吗
  • 山东济南网站新闻网络宣传网站建设咨询
  • 做网站工作量怎么算上海域名网站
  • 中安消防安全网站建设创新设计多功能水杯
  • 足球网站建设赞皇建站建设
  • 网站设计怎么样网页制作网站首页设计
  • 揭阳网站开发网站建设的看法有哪些
  • 营销网站建设软件下载wordpress多主题插件下载地址
  • 网站是公司域名是个人可以微网站套餐
  • 网站搜索优化价格婚恋网站要钱吗
  • 汽车网站开发流程深圳的网站建设公司流程
  • 如何开一家网站建设公司福州seo关键词排名
  • 网站建设是不是都需要交费网站建设 天猫 保证金
  • 佛山提供网站设计报价网络工程师需要考什么证书