分析:此页面下包含两个接口,查询分类的名称和当前分类下的文章列表,和文章列表不同的是,它不带分页。分类包含两个字段,分类名称和展示名称,我们要把真正的名称查询出来展示在页面上。
分类名称不需要给他添加返回模型,直接返回一个string类型即可,同时给一个查询参数name,添加获取分类名称接口和缓存接口。
//IBlogService.Category.cs /// <summary> /// 获取分类名称 /// </summary> /// <param></param> /// <returns></returns> Task<ServiceResult<string>> GetCategoryAsync(string name); //IBlogCacheService.Category.cs /// <summary> /// 获取分类名称 /// </summary> /// <param></param> /// <param></param> /// <returns></returns> Task<ServiceResult<string>> GetCategoryAsync(string name, Func<Task<ServiceResult<string>>> factory);实现这两个接口。
//BlogCacheService.Category.cs ... public partial class BlogCacheService { private const string KEY_GetCategory = "Blog:Category:GetCategory-{0}"; /// <summary> /// 获取分类名称 /// </summary> /// <param></param> /// <param></param> /// <returns></returns> public async Task<ServiceResult<string>> GetCategoryAsync(string name, Func<Task<ServiceResult<string>>> factory) { return await Cache.GetOrAddAsync(KEY_GetCategory.FormatWith(name), factory, CacheStrategy.ONE_DAY); } } ... //BlogService.Category.cs /// <summary> /// 获取分类名称 /// </summary> /// <param></param> /// <returns></returns> public async Task<ServiceResult<string>> GetCategoryAsync(string name) { return await _blogCacheService.GetCategoryAsync(name, async () => { var result = new ServiceResult<string>(); var category = await _categoryRepository.FindAsync(x => x.DisplayName.Equals(name)); if (null == category) { result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("分类", name)); return result; } result.IsSuccess(category.CategoryName); return result; }); }FormatWith()是扩展方法,ResponseText.WHAT_NOT_EXIST是之前说过的常量,直接查询是否存在当前name的分类,如果不存在给出错误提示,存在的话,则只返回分类名称,在BlogController中添加API。
/// <summary> /// 获取分类名称 /// </summary> /// <param></param> /// <returns></returns> [HttpGet] [Route("category")] public async Task<ServiceResult<string>> GetCategoryAsync(([Required] string name) { return await _blogService.GetCategoryAsync(name); }[Required]Attribute 指定参数name必填。
文章列表通过分类名称查询文章列表和分页查询文章列表返回模型是一样的,只是不用分页,所以直接返回一个列表就可以了,添加通过分类名称查询文章列表和缓存的接口。
//IBlogService.Post.cs /// <summary> /// 通过分类名称查询文章列表 /// </summary> /// <param></param> /// <returns></returns> Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByCategoryAsync(string name); //IBlogCacheService.Post.cs /// <summary> /// 通过分类名称查询文章列表 /// </summary> /// <param></param> /// <param></param> /// <returns></returns> Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByCategoryAsync(string name, Func<Task<ServiceResult<IEnumerable<QueryPostDto>>>> factory);分别实现这两个接口。
//BlogCacheService.Post.cs ... public partial class BlogCacheService { private const string KEY_QueryPostsByCategory = "Blog:Post:QueryPostsByCategory-{0}"; /// <summary> /// 通过分类名称查询文章列表 /// </summary> /// <param></param> /// <param></param> /// <returns></returns> public async Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByCategoryAsync(string name, Func<Task<ServiceResult<IEnumerable<QueryPostDto>>>> factory) { return await Cache.GetOrAddAsync(KEY_QueryPostsByCategory.FormatWith(name), factory, CacheStrategy.ONE_DAY); } } ... //BlogService.Post.cs /// <summary> /// 通过分类名称查询文章列表 /// </summary> /// <param></param> /// <returns></returns> public async Task<ServiceResult<IEnumerable<QueryPostDto>>> QueryPostsByCategoryAsync(string name) { return await _blogCacheService.QueryPostsByCategoryAsync(name, async () => { var result = new ServiceResult<IEnumerable<QueryPostDto>>(); var list = (from posts in await _postRepository.GetListAsync() join categories in await _categoryRepository.GetListAsync() on posts.CategoryId equals categories.Id where categories.DisplayName.Equals(name) orderby posts.CreationTime descending select new PostBriefDto { Title = posts.Title, Url = posts.Url, Year = posts.CreationTime.Year, CreationTime = posts.CreationTime.TryToDateTime() }) .GroupBy(x => x.Year) .Select(x => new QueryPostDto { Year = x.Key, Posts = x.ToList() }); result.IsSuccess(list); return result; }); }