来宾住房和建设局网站,揭阳网站开发定制,wordpress在哪里看访客,室内设计公司取名字上一篇文章使用自定义仓储完成了简单的增删改查案例#xff0c;有心的同学可以看出#xff0c;我们的返回参数一塌糊涂#xff0c;显得很不友好。在实际开发过程中#xff0c;每个公司可能不尽相同#xff0c;但都大同小异#xff0c;我们的返回数据都是包裹在一个公共的… 上一篇文章使用自定义仓储完成了简单的增删改查案例有心的同学可以看出我们的返回参数一塌糊涂显得很不友好。在实际开发过程中每个公司可能不尽相同但都大同小异我们的返回数据都是包裹在一个公共的模型下面的而不是直接返回最终数据在返回参数中显示出当前请求的时间戳是否请求成功如果错误那么错误的消息是什么状态码(状态码可以是我们自己定义的值)等等。可能显得很繁琐没必要但这样做的好处毋庸置疑除了美化了我们的API之外也方便了前端同学的数据处理。我们将统一的返回模型放在.ToolKits层中之前说过这里主要是公共的工具类、扩展方法。新建一个Base文件夹添加响应实体类ServiceResult.cs在Enum文件夹下单独定义一个ServiceResultCode响应码枚举0/1。分别代表 成功和失败。//ServiceResultCode.cs
namespace Meowv.Blog.ToolKits.Base.Enum
{/// summary/// 服务层响应码枚举/// /summarypublic enum ServiceResultCode{/// summary/// 成功/// /summarySucceed 0,/// summary/// 失败/// /summaryFailed 1,}
}
//ServiceResult.cs
using Meowv.Blog.ToolKits.Base.Enum;
using System;namespace Meowv.Blog.ToolKits.Base
{/// summary/// 服务层响应实体/// /summarypublic class ServiceResult{/// summary/// 响应码/// /summarypublic ServiceResultCode Code { get; set; }/// summary/// 响应信息/// /summarypublic string Message { get; set; }/// summary/// 成功/// /summarypublic bool Success Code ServiceResultCode.Succeed;/// summary/// 时间戳(毫秒)/// /summarypublic long Timestamp { get; } (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000;/// summary/// 响应成功/// /summary/// param namemessage/param/// param namedata/param/// returns/returnspublic void IsSuccess(string message ){Message message;Code ServiceResultCode.Succeed;}/// summary/// 响应失败/// /summary/// param namemessage/param/// param namedata/param/// returns/returnspublic void IsFailed(string message ){Message message;Code ServiceResultCode.Failed;}/// summary/// 响应失败/// /summary/// param nameexexception/param/// param namedata/param/// returns/returnspublic void IsFailed(Exception exception){Message exception.InnerException?.StackTrace;Code ServiceResultCode.Failed;}}
}
可以看到还定义了 string 类型的 Messagebool 类型的 SuccessSuccess取决于Code ServiceResultCode.Succeed的结果。还有一个当前的时间戳Timestamp。其中还有IsSuccess(...)和IsFailed(...)方法当我们成功返回数据或者当系统出错或者参数异常的时候执行这一点也不难理解吧。这个返回模型暂时只支持无需返回参数的api使用还需要扩展一下当我们需要返回其它各种复杂类型的数据就行不通了。所以还需要添加一个支持泛型的返回模型新建模型类ServiceResultOfT.cs这里的T就是我们的返回结果然后继承我们的ServiceResult指定T为class。并重新编写一个IsSuccess(...)方法代码如下//ServiceResultOfT.cs
using Meowv.Blog.ToolKits.Base.Enum;namespace Meowv.Blog.ToolKits.Base
{/// summary/// 服务层响应实体(泛型)/// /summary/// typeparam nameT/typeparampublic class ServiceResultT : ServiceResult where T : class{/// summary/// 返回结果/// /summarypublic T Result { get; set; }/// summary/// 响应成功/// /summary/// param nameresult/param/// param namemessage/parampublic void IsSuccess(T result null, string message )
{Message message;Code ServiceResultCode.Succeed;Result result;}}
}
此时针对无需返回参数和需要返回参数的api都可以满足要求了。但是还有一种就没办法了那就是带分页的数据我们都应该知道想要分页数据总数肯定是必不可少的。所以此时还需要扩展一个分页的响应实体当我们使用的时候直接将分页响应实体作为上面写的ServiceResultT中的T参数即可满足需求。新建文件夹Paged添加总数接口IHasTotalCount、返回结果列表接口IListResult//IHasTotalCount.cs
namespace Meowv.Blog.ToolKits.Base.Paged
{public interface IHasTotalCount{/// summary/// 总数/// /summaryint Total { get; set; }}
}//IListResult.cs
using System.Collections.Generic;namespace Meowv.Blog.ToolKits.Base.Paged
{public interface IListResultT{/// summary/// 返回结果/// /summaryIReadOnlyListT Item { get; set; }}
}
IListResultT接受一个参数并将其指定为IReadOnlyList返回。现在来实现IListResult接口新建ListResult实现类继承IListResult在构造函数中为其赋值代码如下//ListResult.cs
using System.Collections.Generic;namespace Meowv.Blog.ToolKits.Base.Paged
{public class ListResultT : IListResultT{IReadOnlyListT item;public IReadOnlyListT Item{get item ?? (item new ListT());set item value;}public ListResult()
{}public ListResult(IReadOnlyListT item)
{Item item;}}
}
最后新建我们的分页响应实体接口IPagedList和分页响应实体实现类PagedList它同时也要接受一个泛型参数 T。接口继承了IListResultT和IHasTotalCount实现类继承ListResultT和IPagedListT在构造函数中为其赋值。代码如下//IPagedList.cs
namespace Meowv.Blog.ToolKits.Base.Paged
{public interface IPagedListT : IListResultT, IHasTotalCount{}
}//PagedList.cs
using Meowv.Blog.ToolKits.Base.Paged;
using System.Collections.Generic;namespace Meowv.Blog.ToolKits.Base
{/// summary/// 分页响应实体/// /summary/// typeparam nameT/typeparampublic class PagedListT : ListResultT, IPagedListT{/// summary/// 总数/// /summarypublic int Total { get; set; }public PagedList(){}public PagedList(int total, IReadOnlyListT result) : base(result){Total total;}}
}
到这里我们的返回模型就圆满了看一下此时下我们的项目层级目录。接下来去实践一下修改我们之前创建的增删改查接口的返回参数。//IBlogService.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Threading.Tasks;namespace Meowv.Blog.Application.Blog
{public interface IBlogService{//Taskbool InsertPostAsync(PostDto dto);TaskServiceResultstring InsertPostAsync(PostDto dto);//Taskbool DeletePostAsync(int id);TaskServiceResult DeletePostAsync(int id);//Taskbool UpdatePostAsync(int id, PostDto dto);TaskServiceResultstring UpdatePostAsync(int id, PostDto dto);//TaskPostDto GetPostAsync(int id);TaskServiceResultPostDto GetPostAsync(int id);}
}
接口全部为异步方式用ServiceResult包裹作为返回模型添加和更新T参数为string类型删除就直接不返回结果然后查询为ServiceResultPostDto再看一下实现类//BlogService.cs
...public async TaskServiceResultstring InsertPostAsync(PostDto dto){var result new ServiceResultstring();var entity new Post{Title dto.Title,Author dto.Author,Url dto.Url,Html dto.Html,Markdown dto.Markdown,CategoryId dto.CategoryId,CreationTime dto.CreationTime};var post await _postRepository.InsertAsync(entity);if (post null){result.IsFailed(添加失败);return result;}result.IsSuccess(添加成功);return result;}public async TaskServiceResult DeletePostAsync(int id){var result new ServiceResult();await _postRepository.DeleteAsync(id);return result;}public async TaskServiceResultstring UpdatePostAsync(int id, PostDto dto){var result new ServiceResultstring();var post await _postRepository.GetAsync(id);if (post null){result.IsFailed(文章不存在);return result;}post.Title dto.Title;post.Author dto.Author;post.Url dto.Url;post.Html dto.Html;post.Markdown dto.Markdown;post.CategoryId dto.CategoryId;post.CreationTime dto.CreationTime;await _postRepository.UpdateAsync(post);result.IsSuccess(更新成功);return result;}public async TaskServiceResultPostDto GetPostAsync(int id){var result new ServiceResultPostDto();var post await _postRepository.GetAsync(id);if (post null){result.IsFailed(文章不存在);return result;}var dto new PostDto{Title post.Title,Author post.Author,Url post.Url,Html post.Html,Markdown post.Markdown,CategoryId post.CategoryId,CreationTime post.CreationTime};result.IsSuccess(dto);return result;}
...
当成功时调用IsSuccess(...)方法当失败时调用IsFailed(...)方法。最终我们返回的是new ServiceResult()或者new ServiceResultT()对象。同时不要忘记在Controller中也需要修改一下如下//BlogController.cs
......public async TaskServiceResultstring InsertPostAsync([FromBody] PostDto dto)......public async TaskServiceResult DeletePostAsync([Required] int id)......public async TaskServiceResultstring UpdatePostAsync([Required] int id, [FromBody] PostDto dto)......public async TaskServiceResultPostDto GetPostAsync([Required] int id)...
...
此时再去我们的Swagger文档发起请求这里我们调用一下查询接口看看返回的样子看看效果吧。本篇内容比较简单主要是包装我们的api让返回结果显得比较正式一点。那么你学会了吗????????????开源地址https://github.com/Meowv/Blog/tree/blog_tutorial