系列文章
- 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目
- 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来
- 基于 abp vNext 和 .NET Core 开发博客项目 - 完善与美化,Swagger登场
- 基于 abp vNext 和 .NET Core 开发博客项目 - 数据访问和代码优先
- 基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查
- 基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型
- 基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁
- 基于 abp vNext 和 .NET Core 开发博客项目 - 接入GitHub,用JWT保护你的API
- 基于 abp vNext 和 .NET Core 开发博客项目 - 异常处理和日志记录
- 基于 abp vNext 和 .NET Core 开发博客项目 - 使用Redis缓存数据
- 基于 abp vNext 和 .NET Core 开发博客项目 - 集成Hangfire实现定时任务处理
- 基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(四)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(四)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(九)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目
上一篇完成了博客文章详情页面的数据展示和基于JWT方式的简单身份验证,本篇继续推进,完成后台分类管理的所有增删改查等功能。
分类管理
在 Admin 文件夹下新建Razor组件,Categories.razor
,设置路由,@page "/admin/categories"
。将具体的展示内容放在组件AdminLayout
中。
@page "/admin/categories"
<AdminLayout>
<Loading />
</AdminLayout>
在这里我会将所有分类展示出来,新增、更新、删除都会放在一个页面上去完成。
先将列表查出来,添加API的返回参数,private ServiceResult<IEnumerable<QueryCategoryForAdminDto>> categories;
,然后再初始化中去获取数据。
//QueryCategoryForAdminDto.cs
namespace Meowv.Blog.BlazorApp.Response.Blog
{
public class QueryCategoryForAdminDto : QueryCategoryDto
{
/// <summary>
/// 主键
/// </summary>
public int Id {
get; set; }
}
}
/// <summary>
/// API返回的分类列表数据
/// </summary>
private ServiceResult<IEnumerable<QueryCategoryForAdminDto>> categories;
/// <summary>
/// 初始化
/// </summary>
/// <returns></returns>
protected override async Task OnInitializedAsync()
{
var token = await Common.GetStorageAsync("token");
Http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
categories = await FetchData();
}
/// <summary>
/// 获取数据
/// </summary>
/// <returns></returns>
private async Task<ServiceResult<IEnumerable<QueryCategoryForAdminDto>>> FetchData()
{
return await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryCategoryForAdminDto>>>("/blog/admin/categories");
}
初始化的时候,需要将我们存在localStorage
中的token读取出来,因为我们后台的API都需要添加 Authorization
Header 请求头才能成功返回数据。
在Blazor添加请求头也是比较方便的,直接Http.DefaultRequestHeaders.Add(...)
即可,要注意的是 token值前面需要加 Bearer
,跟了一个空格不可以省略。
获取数据单独提成了一个方法FetchData()
,因为会频繁用到,现在在页面上将数据绑定进行展示。
@if (categories == null)
{
<Loading />
}
else
{
<div class="post-wrap categories">
<h2 class="post-title">- Categories -</h2>
@if (categories.Success && categories.Result.Any())
{
<div class="categories-card">
@foreach (var item in categories.Result)
{
<div class="card-item">
<div class="categories">
<NavLink title="❌删除" @onclick="@(async () => await DeleteAsync(item.Id))">❌</NavLink>
<NavLink title="📝编辑" @onclick="@(() => ShowBox(item))">📝</NavLink>
<NavLink target="_blank" href="@($"/category/{item.DisplayName}")">
<h3>@item.CategoryName</h3>
<small>(@item.Count)</small>
</NavLink>
</div>
</div>
}
<div class="card-item">
<div class="categories">
<NavLink><h3