日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型

發(fā)布時間:2025/1/21 asp.net 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

基于 abp vNext 和 .NET Core 開發(fā)博客項目 - 統(tǒng)一規(guī)范API,包裝返回模型

轉載于:https://github.com/Meowv/Blog

在實際開發(fā)過程中,每個公司可能不盡相同,但都大同小異,我們的返回數(shù)據(jù)都是包裹在一個公共的模型下面的,而不是直接返回最終數(shù)據(jù),在返回參數(shù)中,顯示出當前請求的時間戳,是否請求成功,如果錯誤那么錯誤的消息是什么,狀態(tài)碼(狀態(tài)碼可以是我們自己定義的值)等等。可能顯得很繁瑣,沒必要,但這樣做的好處毋庸置疑,除了美化了我們的API之外,也方便了前端同學的數(shù)據(jù)處理。

我們將統(tǒng)一的返回模型放在.ToolKits層中,之前說過這里主要是公共的工具類、擴展方法。

新建一個Base文件夾,添加響應實體類ServiceResult.cs,在Enum文件夾下單獨定義一個ServiceResultCode響應碼枚舉,0/1。分別代表 成功和失敗。

//ServiceResultCode.cs
namespace Meowv.Blog.ToolKits.Base.Enum
{
///
/// 服務層響應碼枚舉
///
public enum ServiceResultCode
{
///
/// 成功
///
Succeed = 0,

/// <summary>/// 失敗/// </summary>Failed = 1, }

}
//ServiceResult.cs
using Meowv.Blog.ToolKits.Base.Enum;
using System;

namespace Meowv.Blog.ToolKits.Base
{
///
/// 服務層響應實體
///
public class ServiceResult
{
///
/// 響應碼
///
public ServiceResultCode Code { get; set; }

/// <summary>/// 響應信息/// </summary>public string Message { get; set; }/// <summary>/// 成功/// </summary>public bool Success => Code == ServiceResultCode.Succeed;/// <summary>/// 時間戳(毫秒)/// </summary>public long Timestamp { get; } = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000;/// <summary>/// 響應成功/// </summary>/// <param name="message"></param>/// <param name="data"></param>/// <returns></returns>public void IsSuccess(string message = ""){Message = message;Code = ServiceResultCode.Succeed;}/// <summary>/// 響應失敗/// </summary>/// <param name="message"></param>/// <param name="data"></param>/// <returns></returns>public void IsFailed(string message = ""){Message = message;Code = ServiceResultCode.Failed;}/// <summary>/// 響應失敗/// </summary>/// <param name="exexception></param>/// <param name="data"></param>/// <returns></returns>public void IsFailed(Exception exception){Message = exception.InnerException?.StackTrace;Code = ServiceResultCode.Failed;} }

}
可以看到,還定義了 string 類型的 Message,bool 類型的 Success,Success取決于Code == ServiceResultCode.Succeed的結果。還有一個當前的時間戳Timestamp。

其中還有IsSuccess(…)和IsFailed(…)方法,當我們成功返回數(shù)據(jù)或者當系統(tǒng)出錯或者參數(shù)異常的時候執(zhí)行,這一點也不難理解吧。

這個返回模型暫時只支持無需返回參數(shù)的api使用,還需要擴展一下,當我們需要返回其它各種復雜類型的數(shù)據(jù)就行不通了。所以還需要添加一個支持泛型的返回模型,新建模型類:ServiceResultOfT.cs,這里的T就是我們的返回結果,然后繼承我們的ServiceResult,指定T為class。并重新編寫一個IsSuccess(…)方法,代碼如下:

//ServiceResultOfT.cs
using Meowv.Blog.ToolKits.Base.Enum;

namespace Meowv.Blog.ToolKits.Base
{
///
/// 服務層響應實體(泛型)
///
///
public class ServiceResult : ServiceResult where T : class
{
///
/// 返回結果
///
public T Result { get; set; }

/// <summary>/// 響應成功/// </summary>/// <param name="result"></param>/// <param name="message"></param>public void IsSuccess(T result = null, string message = "")

{
Message = message;
Code = ServiceResultCode.Succeed;
Result = result;
}
}
}
此時針對無需返回參數(shù)和需要返回參數(shù)的api都可以滿足要求了。但是還有一種就沒辦法了,那就是帶分頁的數(shù)據(jù),我們都應該知道想要分頁,數(shù)據(jù)總數(shù)肯定是必不可少的。

所以此時還需要擴展一個分頁的響應實體,當我們使用的時候,直接將分頁響應實體作為上面寫的ServiceResult中的T參數(shù),即可滿足需求。

新建文件夾Paged,添加總數(shù)接口IHasTotalCount、返回結果列表接口IListResult

//IHasTotalCount.cs
namespace Meowv.Blog.ToolKits.Base.Paged
{
public interface IHasTotalCount
{
///
/// 總數(shù)
///
int Total { get; set; }
}
}

//IListResult.cs
using System.Collections.Generic;

namespace Meowv.Blog.ToolKits.Base.Paged
{
public interface IListResult
{
///
/// 返回結果
///
IReadOnlyList Item { get; set; }
}
}
IListResult接受一個參數(shù),并將其指定為IReadOnlyList返回。

現(xiàn)在來實現(xiàn)IListResult接口,新建ListResult實現(xiàn)類,繼承IListResult,在構造函數(shù)中為其賦值,代碼如下:

//ListResult.cs
using System.Collections.Generic;

namespace Meowv.Blog.ToolKits.Base.Paged
{
public class ListResult : IListResult
{
IReadOnlyList item;

public IReadOnlyList<T> Item{get => item ?? (item = new List<T>());set => item = value;}public ListResult()

{
}

public ListResult(IReadOnlyList<T> item)

{
Item = item;
}
}
}
最后新建我們的分頁響應實體接口:IPagedList和分頁響應實體實現(xiàn)類:PagedList,它同時也要接受一個泛型參數(shù) T。

接口繼承了IListResult和IHasTotalCount,實現(xiàn)類繼承ListResult和IPagedList,在構造函數(shù)中為其賦值。代碼如下:

//IPagedList.cs
namespace Meowv.Blog.ToolKits.Base.Paged
{
public interface IPagedList : IListResult, IHasTotalCount
{
}
}

//PagedList.cs
using Meowv.Blog.ToolKits.Base.Paged;
using System.Collections.Generic;

namespace Meowv.Blog.ToolKits.Base
{
///
/// 分頁響應實體
///
///
public class PagedList : ListResult, IPagedList
{
///
/// 總數(shù)
///
public int Total { get; set; }

public PagedList(){}public PagedList(int total, IReadOnlyList<T> result) : base(result){Total = total;} }

}
到這里我們的返回模型就圓滿了,看一下此時下我們的項目層級目錄。

圖片

接下來去實踐一下,修改我們之前創(chuàng)建的增刪改查接口的返回參數(shù)。

//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
{
//Task InsertPostAsync(PostDto dto);
Task<ServiceResult> InsertPostAsync(PostDto dto);

//Task<bool> DeletePostAsync(int id);Task<ServiceResult> DeletePostAsync(int id);//Task<bool> UpdatePostAsync(int id, PostDto dto);Task<ServiceResult<string>> UpdatePostAsync(int id, PostDto dto);//Task<PostDto> GetPostAsync(int id);Task<ServiceResult<PostDto>> GetPostAsync(int id); }

}

接口全部為異步方式,用ServiceResult包裹作為返回模型,添加和更新T參數(shù)為string類型,刪除就直接不返回結果,然后查詢?yōu)?#xff1a;ServiceResult,再看一下實現(xiàn)類:

//BlogService.cs

public async Task<ServiceResult> InsertPostAsync(PostDto dto)
{
var result = new ServiceResult();

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 Task<ServiceResult> DeletePostAsync(int id){var result = new ServiceResult();await _postRepository.DeleteAsync(id);return result;}public async Task<ServiceResult<string>> UpdatePostAsync(int id, PostDto dto){var result = new ServiceResult<string>();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 Task<ServiceResult<PostDto>> GetPostAsync(int id){var result = new ServiceResult<PostDto>();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 ServiceResult()對象。

同時不要忘記在Controller中也需要修改一下,如下:

//BlogController.cs


public async Task<ServiceResult> InsertPostAsync([FromBody] PostDto dto)

...public async Task<ServiceResult> DeletePostAsync([Required] int id)......public async Task<ServiceResult<string>> UpdatePostAsync([Required] int id, [FromBody] PostDto dto)......public async Task<ServiceResult<PostDto>> GetPostAsync([Required] int id)...

此時再去我們的Swagger文檔發(fā)起請求,這里我們調用一下查詢接口看看返回的樣子,看看效果吧。

圖片

本篇內容比較簡單,主要是包裝我們的api,讓返回結果顯得比較正式一點。那么,你學會了嗎?😁😁😁

開源地址:https://github.com/Meowv/Blog/tree/blog_tutorial

總結

以上是生活随笔為你收集整理的基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。