欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 编程语言 > >内容正文

asp.net

基于 abp vnext 和 .net core 开发博客项目 -凯发k8官方网

发布时间:2025/1/21 18 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 基于 abp vnext 和 .net core 开发博客项目 - 博客接口实战篇(一) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

基于 abp vnext 和 .net core 开发博客项目 - 博客接口实战篇(一)

转载于:https://github.com/meowv/blog

现在博客数据库中的数据是比较混乱的,为了看起来像那么回事,显得正式一点,我先手动搞点数据进去。

图片

搞定了种子数据,就可以去愉快的写接口了,我这里将根据我现在的博客页面去分析所需要接口,感兴趣的去点点。

为了让接口看起来清晰,一目了然,删掉之前在iblogservice中添加的所有接口,将5个自定义仓储全部添加至blogservice中,然后用partial修饰。

//iblogservice.cs
public partial interface iblogservice
{
}

//blogservice.cs
using meowv.blog.application.caching.blog;
using meowv.blog.domain.blog.repositories;

namespace meowv.blog.application.blog.impl
{
public partial class blogservice : servicebase, iblogservice
{
private readonly iblogcacheservice _blogcacheservice;
private readonly ipostrepository _postrepository;
private readonly icategoryrepository _categoryrepository;
private readonly itagrepository _tagrepository;
private readonly iposttagrepository _posttagrepository;
private readonly ifriendlinkrepository _friendlinksrepository;

public blogservice(iblogcacheservice blogcacheservice,ipostrepository postrepository,icategoryrepository categoryrepository,itagrepository tagrepository,iposttagrepository posttagrepository,ifriendlinkrepository friendlinksrepository){_blogcacheservice = blogcacheservice;_postrepository = postrepository;_categoryrepository = categoryrepository;_tagrepository = tagrepository;_posttagrepository = posttagrepository;_friendlinksrepository = friendlinksrepository;} }

}
在blog文件夹下依次添加接口:iblogservice.post.cs、iblogservice.category.cs、iblogservice.tag.cs、iblogservice.friendlink.cs、iblogservice.admin.cs。

在blog/impl文件夹下添加实现类:iblogservice.post.cs、blogservice.category.cs、blogservice.tag.cs、blogservice.friendlink.cs、blogservice.admin.cs。

同上,.application.caching层也按照这个样子添加。

注意都需要添加partial修饰为局部的接口和实现类,所有文章相关的接口放在iblogservice.post.cs中,分类放在iblogservice.category.cs,标签放在iblogservice.tag.cs,友链放在iblogservice.friendlink.cs,后台增删改所有接口放在iblogservice.admin.cs,最终效果图如下:

图片

文章列表页

图片

分析:列表带分页,以文章发表的年份分组,所需字段:标题、链接、时间、年份。

在.application.contracts层blog文件夹下添加返回的模型:querypostdto.cs。

//querypostdto.cs
using system.collections.generic;

namespace meowv.blog.application.contracts.blog
{
public class querypostdto
{
///
/// 年份
///
public int year { get; set; }

/// /// posts/// public ienumerable posts { get; set; } }

}
模型为一个年份和一个文章列表,文章列表模型:postbriefdto.cs。

//postbriefdto.cs
namespace meowv.blog.application.contracts.blog
{
public class postbriefdto
{
///
/// 标题
///
public string title { get; set; }

/// /// 链接/// public string url { get; set; }/// /// 年份/// public int year { get; set; }/// /// 创建时间/// public string creationtime { get; set; } }

}
搞定,因为返回时间为英文格式,所以creationtime给了字符串类型。

在iblogservice.post.cs中添加接口分页查询文章列表querypostsasync,肯定需要接受俩参数分页页码和分页数量。还是去添加一个公共模型paginginput吧,在.application.contracts下面。

//paginginput.cs
using system.componentmodel.dataannotations;

namespace meowv.blog.application.contracts
{
///
/// 分页输入参数
///
public class paginginput
{
///
/// 页码
///
[range(1, int.maxvalue)]
public int page { get; set; } = 1;

/// /// 限制条数/// [range(10, 30)]public int limit { get; set; } = 10; }

}
page设置默认值为1,limit设置默认值为10,range attribute设置参数可输入大小限制,于是这个分页查询文章列表的接口就是这个样子的。

//iblogservice.post.cs
public partial interface iblogservice
{
///
/// 分页查询文章列表
///
///
///
task> querypostsasync(paginginput input);
}
serviceresult和pagedlist是之前添加的统一返回模型,紧接着就去添加一个分页查询文章列表缓存接口,和上面是对应的。

//iblogcacheservice.post.cs
using meowv.blog.application.contracts;
using meowv.blog.application.contracts.blog;
using meowv.blog.toolkits.base;
using system;
using system.threading.tasks;

namespace meowv.blog.application.caching.blog
{
public partial interface iblogcacheservice
{
///
/// 分页查询文章列表
///
///
///
///
task> querypostsasync(paginginput input, func>> factory);
}
}
分别实现这两个接口。

//blogcacheservice.post.cs
public partial class blogcacheservice
{
private const string key_queryposts = “blog:post:queryposts-{0}-{1}”;

/// /// 分页查询文章列表 /// /// /// /// public async task>> querypostsasync(paginginput input, func>>> factory) {return await cache.getoraddasync(key_queryposts.formatwith(input.page, input.limit), factory, cachestrategy.one_day); }

}

//blogservice.post.cs
///
/// 分页查询文章列表
///
///
///
public async task> querypostsasync(paginginput input)
{
return await _blogcacheservice.querypostsasync(input, async () =>
{
var result = new serviceresult();

var count = await _postrepository.getcountasync();var list = _postrepository.orderbydescending(x => x.creationtime).pagebyindex(input.page, input.limit).select(x => new postbriefdto{title = x.title,url = x.url,year = x.creationtime.year,creationtime = x.creationtime.trytodatetime()}).groupby(x => x.year).select(x => new querypostdto{year = x.key,posts = x.tolist()}).tolist();result.issuccess(new pagedlist(count.trytoint(), list));return result; });

}
pagebyindex(…)、trytodatetime()是.toolkits层添加的扩展方法,先查询总数,然后根据时间倒序,分页,筛选出所需字段,根据年份分组,输出,结束。

在blogcontroller中添加api。

///
/// 分页查询文章列表
///
///
///
[httpget]
[route(“posts”)]
public async task> querypostsasync([fromquery] paginginput input)
{
return await _blogservice.querypostsasync(input);
}
[fromquery]设置input为从url进行查询参数,编译运行看效果。

图片

已经可以查询出数据,并且缓存至redis中。

获取文章详情

图片

分析:文章详情页,文章的标题、作者、发布时间、所属分类、标签列表、文章内容(html和markdown)、链接、上下篇的标题和链接。

创建返回模型:postdetaildto.cs

//postdetaildto.cs
using system.collections.generic;

namespace meowv.blog.application.contracts.blog
{
public class postdetaildto
{
///
/// 标题
///
public string title { get; set; }

/// /// 作者/// public string author { get; set; }/// /// 链接/// public string url { get; set; }/// /// html/// public string html { get; set; }/// /// markdown/// public string markdown { get; set; }/// /// 创建时间/// public string creationtime { get; set; }/// /// 分类/// public categorydto category { get; set; }/// /// 标签列表/// public ienumerable tags { get; set; }/// /// 上一篇/// public postforpageddto previous { get; set; }/// /// 下一篇/// public postforpageddto next { get; set; } }

}
同时添加categorydto、tagdto、postforpageddto。

//categorydto.cs
namespace meowv.blog.application.contracts.blog
{
public class categorydto
{
///
/// 分类名称
///
public string categoryname { get; set; }

/// /// 展示名称/// public string displayname { get; set; } }

}

//tagdto.cs
namespace meowv.blog.application.contracts.blog
{
public class tagdto
{
///
/// 标签名称
///
public string tagname { get; set; }

/// /// 展示名称/// public string displayname { get; set; } }

}

//postforpageddto.cs
namespace meowv.blog.application.contracts.blog
{
public class postforpageddto
{
///
/// 标题
///
public string title { get; set; }

/// /// 链接/// public string url { get; set; } }

}
添加获取文章详情接口和缓存的接口。

//iblogservice.post.cs
public partial interface iblogservice
{
///
/// 根据url获取文章详情
///
///
///
task getpostdetailasync(string url);
}
//iblogcacheservice.post.cs
public partial interface iblogcacheservice
{
///
/// 根据url获取文章详情
///
///
///
task getpostdetailasync(string url, func> factory);
}
分别实现这两个接口。

//blogcacheservice.post.cs
public partial class blogcacheservice
{
private const string key_getpostdetail = “blog:post:getpostdetail-{0}”;

/// /// 根据url获取文章详情 /// /// /// /// public async task> getpostdetailasync(string url, func>> factory) {return await cache.getoraddasync(key_getpostdetail.formatwith(url), factory, cachestrategy.one_day); }

}
//blogservice.post.cs
///
/// 根据url获取文章详情
///
///
///
public async task getpostdetailasync(string url)
{
return await _blogcacheservice.getpostdetailasync(url, async () =>
{
var result = new serviceresult();

var post = await _postrepository.findasync(x => x.url.equals(url));if (null == post){result.isfailed(responsetext.what_not_exist.formatwith("url", url));return result;}var category = await _categoryrepository.getasync(post.categoryid);var tags = from post_tags in await _posttagrepository.getlistasync()join tag in await _tagrepository.getlistasync()on post_tags.tagid equals tag.idwhere post_tags.postid.equals(post.id)select new tagdto{tagname = tag.tagname,displayname = tag.displayname};var previous = _postrepository.where(x => x.creationtime > post.creationtime).take(1).firstordefault();var next = _postrepository.where(x => x.creationtime < post.creationtime).orderbydescending(x => x.creationtime).take(1).firstordefault();var postdetail = new postdetaildto{title = post.title,author = post.author,url = post.url,html = post.html,markdown = post.markdown,creationtime = post.creationtime.trytodatetime(),category = new categorydto{categoryname = category.categoryname,displayname = category.displayname},tags = tags,previous = previous == null ? null : new postforpageddto{title = previous.title,url = previous.url},next = next == null ? null : new postforpageddto{title = next.title,url = next.url}};result.issuccess(postdetail);return result; });

}
responsetext.what_not_exist是定义在meowvblogconsts.cs的常量。

trytodatetime()和列表查询中的扩展方法一样,转换时间为想要的格式。

简单说一下查询逻辑,先根据参数url,查询是否存在数据,如果文章不存在则返回错误消息。

然后根据 post.categoryid 就可以查询到当前文章的分类名称。

联合查询post_tags和tag两张表,指定查询条件post.id,查询当前文章的所有标签。

最后上下篇的逻辑也很简单,上一篇取大于当前文章发布时间的第一篇,下一篇取时间倒序排序并且小于当前文章发布时间的第一篇文章。

最后将所有查询到的数据赋值给输出对象,返回,结束。

在blogcontroller中添加api。

///
/// 根据url获取文章详情
///
///
///
[httpget]
[route(“post”)]
public async task getpostdetailasync(string url)
{
return await _blogservice.getpostdetailasync(url);
}
编译运行,然后输入url查询一条文章详情数据。

图片

成功输出预期内容,缓存同时也是ok的。

开源地址:https://github.com/meowv/blog/tree/blog_tutorial

总结

以上是凯发k8官方网为你收集整理的基于 abp vnext 和 .net core 开发博客项目 - 博客接口实战篇(一)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

  • 上一篇:
  • 下一篇:
网站地图