返回目录
之前写到使用.net core ABP 和Angular模板构建项目,创建后端服务。文章地址:http://www.jianshu.com/p/fde1ea20331f
创建完成后的api基本是不能用的,现在根据我们自己的业务逻辑来实现后端服务。
部分业务逻辑流程图
创建Dto并添加数据校验
关于ABP的数据校验可以参考我这篇文章:http://www.jianshu.com/p/144f5cdd3ac8
ICustomValidate 接口用于自定义数据验证,IShouldNormalize接口用于数据标准化
这里就直接贴代码了
namespace MZC.Blog.Notes
{
///
/// 创建的时候不需要太多信息,内容更新主要依靠update
/// 在用户点击创建的时候数据库便创建数据,在用户编辑过程中自动更新保存数据。
///
public class CreateNoteDto : IShouldNormalize
{
///
/// 创建时间
///
public DateTime? CreationTime { get; set; }
///
/// 创建人
///
public long CreatorUserId { get; set; }
///
/// 内容的数据类型 markdown内容,html内容,或者其他
///
public int TextType { get; set; }
public void Normalize()
{
if (!CreationTime.HasValue) CreationTime = DateTime.Now;
}
}
///
/// 自动更新所传的数据
///
public class UpdateNoteDto : EntityDto, IShouldNormalize
{
///
/// 标题
///
public string Title { get; set; }
///
/// 内容
///
public string Content { get; set; }
///
/// 上次修改时间
///
public DateTime? LastModificationTime { get; set; }
public virtual void Normalize()
{
if (!LastModificationTime.HasValue)
{
LastModificationTime = DateTime.Now;
}
}
}
///
/// 发布更新时所用
///
public class PublicNoteDto : UpdateNoteDto, ICustomValidate, IShouldNormalize
{
///
/// 简单描述,用于微信推送时的描述或者其他
///
public string Des { get; set; }
///
/// 封面图片,可用于微信推送时或者其他
///
[Required]
public string Img { get; set; }
///
/// 关键字,可用于搜索,分类等
///
public string Tags { get; set; }
///
/// 是否发布
///
public bool? IsPublic { get; set; }
public override void Normalize()
{
base.Normalize();
IsPublic = true;
}
public void AddValidationErrors(CustomValidationContext context)
{
if (string.IsNullOrEmpty(Des))
{
string error = "描述不能为空!";
context.Results.Add(new ValidationResult(error));
}
if (Des.Length < 10)
{
string error = "描述不能少于10个字!";
context.Results.Add(new ValidationResult(error));
}
if (Des.Length > 200)
{
string error = "描述不能大于200个字!";
context.Results.Add(new ValidationResult(error));
}
}
}
///
/// 用于列表展示
///
public class NoteDto : EntityDto
{
///
/// 标题
///
public string Title { get; set; }
///
/// 创建时间
///
public string CreationTime { get; set; }
///
/// 点赞次数
///
public long Like { get; set; }
///
/// 收藏次数
///
public long Collect { get; set; }
///
/// 浏览次数
///
public long Scan { get; set; }
///
/// 是否发布
///
public string IsPublic { get; set; }
}
public class GetNoteListDto: PagedResultRequestDto
{
///
/// 用于搜索的关键字
///
public string key { get; set; }
}
}
创建映射
创建NoteMapProfile.cs文件,并添加相关映射
关于ABP框架映射的更多内容请参考我这篇文章:http://www.jianshu.com/p/6ef125e873e9
namespace MZC.Blog.Notes
{
public class NoteMapProfile : Profile
{
public NoteMapProfile()
{
CreateMap();
CreateMap();
CreateMap();
//使用自定义解析
CreateMap().ForMember(x=>x.IsPublic,opt=> {
opt.ResolveUsing();
});
CreateMap();
}
}
///
/// 自定义解析
///
public class NoteToNoteDtoResolver : IValueResolver
{
public string Resolve(Note source, NoteDto destination, string destMember, ResolutionContext context)
{
return source.IsPublic ? "已发布" : "未发布";
}
}
}
使用授权
关于ABP授权详细的介绍和使用请看我的另一篇文章:http://www.jianshu.com/p/6e224f4f9705
在core项目Authorization文件夹下有模板提供的授权模块。
在PermissionNames 中定义权限,在AuthorizationProvider中添加定义的权限,然后再项目中就可以通过AbpAuthorize特性或者PermissionChecker类来验证
public static class PermissionNames
{
public const string Pages_Tenants = "Pages.Tenants";
public const string Pages_Users = "Pages.Users";
public const string Pages_Roles = "Pages.Roles";
///
/// 博客管理页面权限
///
public const string Pages_Blogs = "Pages.Blogs";
public const string Pages_Blogs_Notes = "Pages.Blogs.Notes";
public const string Blogs_Notes_Edit = "Pages.Blogs.Notes.Edit";
public const string Blogs_Notes_Delete = "Pages.Blogs.Notes.Delete";
}
public class MZCAuthorizationProvider : AuthorizationProvider
{
public override void SetPermissions(IPermissionDefinitionContext context)
{
context.CreatePermission(PermissionNames.Pages_Users, L("Users"));
context.CreatePermission(PermissionNames.Pages_Roles, L("Roles"));
context.CreatePermission(PermissionNames.Pages_Tenants, L("Tenants"), multiTenancySides: MultiTenancySides.Host);
var BlogPermission = context.CreatePermission(PermissionNames.Pages_Blogs, L("Blogs"));
var NotePermission = BlogPermission.CreateChildPermission(PermissionNames.Pages_Blogs_Notes,L("Notes"));
NotePermission.CreateChildPermission(PermissionNames.Blogs_Notes_Edit, L("EditNotes"));
NotePermission.CreateChildPermission(PermissionNames.Blogs_Notes_Delete, L("DeleteNotes"));
}
private static ILocalizableString L(string name)
{
return new LocalizableString(name, MZCConsts.LocalizationSourceName);
}
}
完善我们的服务和接口
因为是自己的博客系统,没必要那么麻烦就只使用了入口权限定义在类的上面。
public interface INoteAppServer: IAsyncCrudAppService
{
Task PublicNote(PublicNoteDto input);
Task GetNote(EntityDto input);
}
[AbpAuthorize(PermissionNames.Pages_Blogs_Notes)]
public class NoteAppServer : AsyncCrudAppService, INoteAppServer
{
public NoteAppServer(IRepository repository)
: base(repository)
{
}
public override async Task Create(CreateNoteDto input)
{
var note = ObjectMapper.Map(input);
var result = await Repository.InsertAsync(note);
return ObjectMapper.Map(result);
}
public async Task PublicNote(PublicNoteDto input)
{
var note = Repository.Get(input.Id);
ObjectMapper.Map(input,note);
var result = await Repository.UpdateAsync(note);
}
public override async Task Update(UpdateNoteDto input)
{
var note = Repository.Get(input.Id);
ObjectMapper.Map(input,note);
var result = await Repository.UpdateAsync(note);
return ObjectMapper.Map(result);
}
public override async Task> GetAll(GetNoteListDto input)
{
var data = Repository.GetAll().Where(m => !m.IsDeleted);
data = data.WhereIf(!string.IsNullOrEmpty(input.key), m => m.Title.Contains(input.key) || m.Tags.Contains(input.key));
int count = await data.CountAsync();
var notes = await data.OrderByDescending(q => q.CreationTime)
.PageBy(input)
.ToListAsync();
return new PagedResultDto()
{
TotalCount = count,
Items = ObjectMapper.Map>(notes)
};
}
public async Task GetNote(EntityDto input)
{
var note = await Repository.GetAsync(input.Id);
return ObjectMapper.Map(note);
}
}