这是一个使用ASP.net core 5.0创建Razor Page应用程序解决方案模板。遵循Clean Architecture的原则,最求简洁的代码风格和实现快速开发小型的web业务系统的目标,不断优化和重构中持续发展起来的。该项目从最早的asp.net mvc5 到 asp.net core 3.1再到现在最新的asp.net core 5.0 Razor Page,从简单三层结构到N层结构再到现在流行的CQRS模式,一遍一遍的再重构,在这过程中也真的体会到系统架构的重要性和在优秀的框架下开发系统是一件都么愉快的事情。
介绍
- Github: neozhu/RazorPageCleanArchitecture
- Demo: http://razor.i247365.net/
Technologies
- ASP.NET Core 5
- Entity Framework Core 5
- SmartAdmin - Responsive WebApp
- Razor Pages
- Jquery EasyUI
- MediatR
- AutoMapper
- FluentValidation
- NUnit, FluentAssertions, Moq & Respawn
- Docker
特点
- 遵循Clean Architecture原则什么是Clean Architecture
- 非常漂亮的用户界面SmartAdmin - Responsive WebApp
- 遵循CQRS模式极简的代码风格什么是CQRS
- 实现了基本的CRUD功能
- 实现了基本的认证和授权功能
- 支持多语言切换
项目结构
- 项目结构参考jasontaylordev/CleanArchitecture
基本功能预览
- 新增
- 修改
- 删除
- 查询
- 导入Excel
- 下载模板
- 导出Excel
用户管理
- 新增
- 修改
- 删除
- 查询
- 导入Excel
- 下载模板
- 导出Excel
- 重置密码
- 角色管理
角色管理
- 新增
- 修改
- 删除
- 查询
- 导入Excel
- 下载模板
- 导出Excel
- 授权管理
如何开始
- 在Domain project中新增一个Entity,比如Customer客户信息
public partial class Customer : AuditableEntity, IHasDomainEvent
{
public int Id { get; set; }
public string Name { get; set; }
public string NameOfEnglish { get; set; }
public string GroupName { get; set; }
public PartnerType PartnerType { get; set; }
public string Region { get; set; }
public string Sales { get; set; }
public string RegionSalesDirector { get; set; }
public string Address { get; set; }
public string AddressOfEnglish { get; set; }
public string Contract { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public string Fax { get; set; }
public string Comments { get; set; }
public List DomainEvents { get; set; } = new();
}
-
在Application project中实现具体的功能请遵循CQRS模式
- Command
- AddEdit
- Delete
- Import
- DTOs
- Eventhandlers
- Queries
- Export
- PaginationQuery
- 在SmartAdmin.WebUI中添加UI页面
@page
@using CleanArchitecture.Razor.Domain.Enums
@using CleanArchitecture.Razor.Infrastructure.Constants.Permission
@model SmartAdmin.WebUI.Pages.Customers.IndexModel
@inject Microsoft.Extensions.Localization.IStringLocalizer _localizer
@inject Microsoft.AspNetCore.Authorization.IAuthorizationService _authorizationService
@{
ViewData["Title"] = _localizer["Customers"].Value;
ViewData["PageName"] = "customers_index";
ViewData["Category1"] = _localizer["Customers"].Value;
ViewData["Heading"] = _localizer["Customers"].Value;
ViewData["PageDescription"] = _localizer["See all available options"].Value;
ViewData["PreemptiveClass"] = "Default";
var _canCreate = await _authorizationService.AuthorizeAsync(User, null, Permissions.Customers.Create);
var _canEdit = await _authorizationService.AuthorizeAsync(User, null, Permissions.Customers.Edit);
var _canDelete = await _authorizationService.AuthorizeAsync(User, null, Permissions.Customers.Delete);
var _canSearch = await _authorizationService.AuthorizeAsync(User, null, Permissions.Customers.Search);
var _canImport = await _authorizationService.AuthorizeAsync(User, null, Permissions.Customers.Import);
var _canExport = await _authorizationService.AuthorizeAsync(User, null, Permissions.Customers.Export);
}
@section HeadBlock {
}
@_localizer["Customers"]
@_localizer["See all available options"]
@if (_canCreate.Succeeded)
{
}
@if (_canDelete.Succeeded)
{
}
@if (_canSearch.Succeeded)
{
}
@if (_canImport.Succeeded)
{
}
@if (_canExport.Succeeded)
{
}
@await Component.InvokeAsync("ImportExcel", new { importUri = Url.Page("/Customers/Index") + "?handler=Import",
getTemplateUri = @Url.Page("/Customers/Index") + "?handler=CreateTemplate",
onImportedSucceeded = "reload()" })
@section ScriptsBlock {
}
我的项目成果
网站 | 账号/密码 | 截图 |
---|---|---|
http://tms.i247365.net/ TMS 运输管理系统 | [email protected]/123456 |
|
http://manage.i247365.net/ 委托业务内控管理系统 | demo/123456 |
|
http://check.i247365.net/ 人脸考勤管理系统 | demo/123456 |
|
http://supplier.i247365.net/ 供应商询价系统 | demo/123456 |
|
http://iot.i247365.net/ 智能水务综合管理平台 | demo/123456 |
|
http://book.i247365.net/ 小型图书管理工具 | demo/123456 |
|
最后
keep coding, enjoy coding.
如果你喜欢这个项目,请记得在Github上点赞,谢谢
https://github.com/neozhu/RazorPageCleanArchitecture