基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)
基于 abp vNext 和 .NET Core 開發(fā)博客項(xiàng)目 - 博客接口實(shí)戰(zhàn)篇(三)
轉(zhuǎn)載于:https://github.com/Meowv/Blog
上篇文章完成了分類和標(biāo)簽頁面相關(guān)的共6個(gè)接口,本篇繼續(xù)來寫博客增刪改查API的業(yè)務(wù)。
供前端查詢用的接口還剩下一個(gè),這里先補(bǔ)上。
友鏈列表
圖片
分析:返回標(biāo)題和對應(yīng)的鏈接即可,傳輸對象FriendLinkDto.cs。
//FriendLinkDto.cs
namespace Meowv.Blog.Application.Contracts.Blog
{
public class FriendLinkDto
{
///
/// 標(biāo)題
///
public string Title { get; set; }
}
添加查詢友鏈列表接口和緩存接口。
//IBlogService.FriendLink.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Blog
{
public partial interface IBlogService
{
///
/// 查詢友鏈列表
///
///
Task<ServiceResult<IEnumerable>> QueryFriendLinksAsync();
}
}
//IBlogCacheService.FriendLink.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Caching.Blog
{
public partial interface IBlogCacheService
{
///
/// 查詢友鏈列表
///
///
///
Task<ServiceResult<IEnumerable>> QueryFriendLinksAsync(Func<Task<ServiceResult<IEnumerable>>> factory);
}
}
接下來,實(shí)現(xiàn)他們。
//BlogCacheService.FriendLink.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using static Meowv.Blog.Domain.Shared.MeowvBlogConsts;
namespace Meowv.Blog.Application.Caching.Blog.Impl
{
public partial class BlogCacheService
{
private const string KEY_QueryFriendLinks = “Blog:FriendLink:QueryFriendLinks”;
}
//BlogService.FriendLink.cs
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.Domain.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Blog.Impl
{
public partial class BlogService
{
///
/// 查詢友鏈列表
///
///
public async Task<ServiceResult<IEnumerable>> QueryFriendLinksAsync()
{
return await _blogCacheService.QueryFriendLinksAsync(async () =>
{
var result = new ServiceResult<IEnumerable>();
}
直接查詢所有的友鏈數(shù)據(jù),這里使用前面講到的AutoMapper處理對象映射,將IEnumerable轉(zhuǎn)換為IEnumerable。
在MeowvBlogAutoMapperProfile.cs中添加一條配置:CreateMap<FriendLink, FriendLinkDto>();,在BlogController中添加API。
///
/// 查詢友鏈列表
///
///
[HttpGet]
[Route(“friendlinks”)]
public async Task<ServiceResult<IEnumerable>> QueryFriendLinksAsync()
{
return await _blogService.QueryFriendLinksAsync();
}
編譯運(yùn)行,打開查詢友鏈的API,此時(shí)沒數(shù)據(jù),手動(dòng)添加幾條數(shù)據(jù)進(jìn)去再試試吧。
圖片
文章管理
圖片
后臺(tái)文章管理包含:文章列表、新增、更新、刪除文章,接下來依次完成這些接口。
文章列表
這里的文章列表和前臺(tái)的文章列表差不多,就是多了一個(gè)Id,以供編輯和刪除使用,所以可以新建一個(gè)模型類QueryPostForAdminDto繼承QueryPostDto,添加PostBriefForAdminDto繼承PostBriefDto同時(shí)新增一個(gè)字段主鍵Id。
在QueryPostForAdminDto中隱藏基類成員Posts,使用新的接收類型:IEnumerable。
//PostBriefForAdminDto.cs
namespace Meowv.Blog.Application.Contracts.Blog
{
public class PostBriefForAdminDto : PostBriefDto
{
///
/// 主鍵
///
public int Id { get; set; }
}
}
//QueryPostForAdminDto.cs
using System.Collections.Generic;
namespace Meowv.Blog.Application.Contracts.Blog
{
public class QueryPostForAdminDto : QueryPostDto
{
///
/// Posts
///
public new IEnumerable Posts { get; set; }
}
}
添加分頁查詢文章列表的接口:QueryPostsForAdminAsync(),關(guān)于后臺(tái)的一些接口就不添加緩存了。
//IBlogService.Admin.cs
using Meowv.Blog.Application.Contracts;
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Blog
{
public partial interface IBlogService
{
///
/// 分頁查詢文章列表
///
///
///
Task<ServiceResult<PagedList>> QueryPostsForAdminAsync(PagingInput input);
}
}
然后實(shí)現(xiàn)這個(gè)接口。
//BlogService.Admin.cs
using Meowv.Blog.Application.Contracts;
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using Meowv.Blog.ToolKits.Extensions;
using System.Linq;
using System.Threading.Tasks;
namespace Meowv.Blog.Application.Blog.Impl
{
public partial class BlogService
{
///
/// 分頁查詢文章列表
///
///
///
public async Task<ServiceResult<PagedList>> QueryPostsForAdminAsync(PagingInput input)
{
var result = new ServiceResult<PagedList>();
}
實(shí)現(xiàn)邏輯也非常簡單和之前一樣,就是在Select的時(shí)候多了一個(gè)Id,添加一個(gè)新的Controller:BlogController.Admin.cs,添加這個(gè)接口。
//BlogController.Admin.cs
using Meowv.Blog.Application.Contracts;
using Meowv.Blog.Application.Contracts.Blog;
using Meowv.Blog.ToolKits.Base;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using static Meowv.Blog.Domain.Shared.MeowvBlogConsts;
namespace Meowv.Blog.HttpApi.Controllers
{
public partial class BlogController
{
///
/// 分頁查詢文章列表
///
///
///
[HttpGet]
[Authorize]
[Route(“admin/posts”)]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task<ServiceResult<PagedList>> QueryPostsForAdminAsync([FromQuery] PagingInput input)
{
return await _blogService.QueryPostsForAdminAsync(input);
}
}
}
因?yàn)槭呛笈_(tái)的接口,所以加上AuthorizeAttribute,指定接口組為GroupName_v2,參數(shù)方式為[FromQuery]。
當(dāng)沒有進(jìn)行授權(quán)的時(shí)候,是無法訪問接口的。
圖片
新增文章
圖片
在做新增文章的時(shí)候要注意幾點(diǎn),不是單純的添加文章數(shù)據(jù)就結(jié)束了,要指定文章分類,添加文章的標(biāo)簽。添加標(biāo)簽我這里是從標(biāo)簽庫中去取得數(shù)據(jù),只存標(biāo)簽Id,所以添加標(biāo)簽的時(shí)候就可能存在添加了標(biāo)簽庫中已有的標(biāo)簽。
新建一個(gè)新增和更新文章的通用輸出參數(shù)模型類,起名:EditPostInput,繼承PostDto,然后添加標(biāo)簽Tags字段,返回類型IEnumerable。
//EditPostInput.cs
using System.Collections.Generic;
namespace Meowv.Blog.Application.Contracts.Blog.Params
{
public class EditPostInput : PostDto
{
///
/// 標(biāo)簽列表
///
public IEnumerable Tags { get; set; }
}
}
添加新增文章的接口:InsertPostAsync。
///
/// 新增文章
///
///
///
Task InsertPostAsync(EditPostInput input);
然后去實(shí)現(xiàn)這個(gè)接口,實(shí)現(xiàn)之前,配置AutoMapper實(shí)體映射。
CreateMap<EditPostInput, Post>().ForMember(x => x.Id, opt => opt.Ignore());
將EditPostInput轉(zhuǎn)換為Post,并且忽略Id字段。
///
/// 新增文章
///
///
///
public async Task InsertPostAsync(EditPostInput input)
{
var result = new ServiceResult();
}
URL字段,根據(jù)創(chuàng)建時(shí)間按照yyyy/MM/dd/name/格式拼接。
然后找出是否有新標(biāo)簽,有的話批量添加至標(biāo)簽表。
再根據(jù)input.Tags構(gòu)建PostTag列表,也進(jìn)行批量保存,這樣才算是新增好一篇文章,最后輸出ResponseText.INSERT_SUCCESS常量,提示成功。
在BlogController.Admin.cs添加API。
///
/// 新增文章
///
///
///
[HttpPost]
[Authorize]
[Route(“post”)]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task InsertPostAsync([FromBody] EditPostInput input)
{
return await _blogService.InsertPostAsync(input);
}
圖片
更新文章
更新操作和新增操作輸入?yún)?shù)一樣,只新增一個(gè)Id用來標(biāo)識(shí)更新那篇文章,添加UpdatePostAsync更新文章接口。
///
/// 更新文章
///
///
///
///
Task UpdatePostAsync(int id, EditPostInput input);
同樣的實(shí)現(xiàn)這個(gè)接口。
///
/// 更新文章
///
///
///
///
public async Task UpdatePostAsync(int id, EditPostInput input)
{
var result = new ServiceResult();
}
ResponseText.UPDATE_SUCCESS是常量更新成功。
先根據(jù)Id查詢到數(shù)據(jù)庫中的這篇文章數(shù)據(jù),然后根據(jù)input參數(shù),修改需要修改的數(shù)據(jù),最后保存。
注意的是,如果修改的時(shí)候修改了標(biāo)簽,有可能新增也有可能刪除,也許會(huì)又有新增又有刪除。
這時(shí)候就需要注意,這里做了一個(gè)比較通用的方法,找到數(shù)據(jù)庫中當(dāng)前文章Id的所有Tags,然后根據(jù)參數(shù)input.Tags可以找出被刪掉的標(biāo)簽的PostTags的Id,調(diào)用刪除方法刪掉即可,同時(shí)也可以獲取到新增的標(biāo)簽,批量進(jìn)行保存。
完成上面操作后,才保存新加標(biāo)簽與文章對應(yīng)的數(shù)據(jù),最后提示更新成功,在BlogController.Admin添加API。
///
/// 更新文章
///
///
///
///
[HttpPut]
[Authorize]
[Route(“post”)]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task UpdatePostAsync([Required] int id, [FromBody] EditPostInput input)
{
return await _blogService.UpdatePostAsync(id, input);
}
[HttpPut]指定請求方式為put請求,一般需要修改用put,添加用post。
[Required]指定參數(shù)id必填且是FromQuery的方式,input為[FromBody]。
更新一下上面新增的數(shù)據(jù)試試。
圖片
圖片
刪除文章
刪除相對來說就非常簡單了,一般刪除都會(huì)做邏輯刪除,就是避免某些手殘刪除了,有找回的余地,我們這里就直接Delete了,也沒什么重要數(shù)據(jù)。
添加接口:DeletePostAsync。
///
/// 刪除文章
///
///
///
Task DeletePostAsync(int id);
實(shí)現(xiàn)接口。
///
/// 刪除文章
///
///
///
public async Task DeletePostAsync(int id)
{
var result = new ServiceResult();
}
刪除的時(shí)候同樣去查詢一下數(shù)據(jù),來判斷是否存在。
ResponseText.DELETE_SUCCESS是添加的常量刪除成功,刪除成功同時(shí)也要將post_tags表的標(biāo)簽對應(yīng)關(guān)系也干掉才算完整,在BlogController.Admin添加API。
///
/// 刪除文章
///
///
///
[HttpDelete]
[Authorize]
[Route(“post”)]
[ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
public async Task DeletePostAsync([Required] int id)
{
return await _blogService.DeletePostAsync(id);
}
[HttpDelete]指定請求方式是刪除資源,[Required]指定參數(shù)Id必填。
刪掉上面添加的文章看看效果。
圖片
至此,完成了博客文章的增刪改接口,未完待續(xù)…
開源地址:https://github.com/Meowv/Blog/tree/blog_tutorial
總結(jié)
以上是生活随笔為你收集整理的基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于 abp vNext 和 .NET
- 下一篇: 基于 abp vNext 和 .NET