首页
留言板
壁纸
友链
直播
统计
推荐
百度一下
腾讯视频
Search
1
芯宇宙Excel仓库管理系统 三种数据库 | 三种网络部署模式
37 阅读
2
鞋服小店没有大单量,怎么找到低价寄快递渠道?
14 阅读
3
Excel二维码标签插件 固定资产/设备铭牌/合格证批量生成工具支持Excel、WPS,一键批量生成千百个二维码、条形码标签
14 阅读
4
别再花高价寄快递!鞋服商家专属低价寄件小程序,全国 3 元起、大件 20kg 仅 30 元,亲测靠谱
13 阅读
5
鞋服商家低价寄快递渠道推荐,电商寄件小程序散户也能享批发价
11 阅读
默认分类
资讯
技术
VBA
asp
php
分享
鞋运宝
VPS
阿里云
腾讯云
系统
windows
Linux
日常
登录
Search
标签搜索
寄快递
鞋服商家低价寄快递
低价寄快递渠道
VBA
鞋运宝
低价快递小程序
得物快递
EXCEL标签生成插件
鞋服电商
BootstrapBlazor
芯宇宙技术社
累计撰写
12
篇文章
累计收到
1
条评论
首页
栏目
默认分类
资讯
技术
VBA
asp
php
分享
鞋运宝
VPS
阿里云
腾讯云
系统
windows
Linux
日常
页面
留言板
壁纸
友链
直播
统计
推荐
百度一下
腾讯视频
搜索到
5
篇与
的结果
2026-07-29
Blazor 完整学习教程(分阶段,适配 BootstrapBlazor 企业开发)
Blazor 开发指南一、基础认知:Blazor 两种模式区别1. Blazor Server(你当前项目使用)运行机制:UI 在服务器渲染,客户端仅维持 SignalR 长连接优点:上手简单无需单独后端接口可直接注入 Identity、EF Core缺点:并发高时服务器压力大断网页面无交互适用场景:内部管理系统后台系统ERP 系统进销存系统(你的业务场景)2. Blazor WebAssembly(Wasm)运行机制:.NET 运行时下载到浏览器,前端独立运行优点:离线可用服务器负载低缺点:首次加载慢不能直接访问数据库,必须写后端 API适用场景:面向公网的轻量化页面注意:你的项目是 Blazor Server + BootstrapBlazor + Identity,教程全部围绕 Server 模式讲解。二、环境搭建(零基础)1. 必备工具Visual Studio 2022(17.5+)安装组件:ASP.NET 和 Web 开发.NET SDK.NET 8(推荐,长期支持).NET 92. NuGet 包配置<!-- BootstrapBlazor UI组件库 --> <PackageReference Include="BootstrapBlazor" Version="8.3.0" /> <!-- 身份认证 --> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" /> <!-- 数据库EF Core --> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />3. 创建项目步骤VS 创建新项目 → ASP.NET Core 空 / Blazor Server 应用配置项目名称,框架选择 .NET 8集成 BootstrapBlazor 关键两步:// Program.cs builder.Services.AddBootstrapBlazor();<!-- App.razor --> <BootstrapBlazorRoot> <Routes /> </BootstrapBlazorRoot>三、Blazor 核心基础语法(Razor 组件)1. 组件文件结构 .razor@page "/路由地址" <!-- 页面路由 --> @inject 类型 变量名 <!-- 依赖注入 --> @using 命名空间 <!-- 引入类 --> @code {} <!-- C# 逻辑、属性、方法 --> <!-- HTML 混合 C# 代码 -->2. 数据绑定单向绑定:<p>用户名:@UserName</p> @code { private string UserName = "admin"; }双向绑定(登录页使用):<BootstrapInput @bind-Value="LoginModel.UserName" PlaceHolder="账号"/>3. 条件渲染@if (IsLogin) { <span>欢迎 @UserName</span> } else { <a href="/login">去登录</a> } @code { private bool IsLogin = false; private string UserName = ""; }4. 循环渲染@foreach (var item in UserList) { <Card Title="@item.UserName"></Card> } @code { private List<User> UserList = new(); }5. 事件绑定<Button OnClick="SubmitLogin">登录</Button> @code { private async Task SubmitLogin() { // 登录逻辑 } }四、依赖注入(项目核心)1. 三种生命周期AddScoped:每次页面请求创建实例(最常用,AuthHelper、DbContext)AddSingleton:全局单例,程序启动创建(配置、通用工具)AddTransient:每次注入都新建(轻量工具类)2. Program.cs 注册服务// 作用域服务,每个用户会话独立实例 builder.Services.AddScoped<AuthHelper>(); // BootstrapBlazor全局UI服务 builder.Services.AddBootstrapBlazor(); // Identity认证 builder.Services.AddDefaultIdentity<AppUser>() .AddRoles<IdentityRole>() .AddEntityFrameworkStores<AppDbContext>();3. 页面/组件注入使用@inject AuthHelper AuthHelper @inject ToastService Toast @inject NavigationManager Nav五、表单验证(登录页面 ValidateForm)1. 数据注解验证public class LoginDto { [Required(ErrorMessage = "请输入账号")] public string UserName { get; set; } = ""; [Required(ErrorMessage = "请输入密码")] public string Password { get; set; } = ""; }2. BootstrapBlazor ValidateForm 完整模板<ValidateForm Model="@LoginModel" OnValidSubmit="SubmitLogin"> <BootstrapInput @bind-Value="LoginModel.UserName" PlaceHolder="账号"/> <BootstrapPassword @bind-Value="LoginModel.Password" PlaceHolder="密码"/> <Button ButtonType="ButtonType.Submit" Text="登录"/> </ValidateForm>六、ASP.NET Core Identity 身份认证(AuthHelper)1. 核心三个类UserManager:用户增删改查、注册、改密码SignInManager:登录、退出、密码校验、账号锁定RoleManager:角色管理(管理员/普通用户)2. 封装通用 AuthHelperpublic class AuthHelper { private readonly SignInManager<AppUser> _signInManager; private readonly UserManager<AppUser> _userManager; public AuthHelper(SignInManager<AppUser> signInManager, UserManager<AppUser> userManager) { _signInManager = signInManager; _userManager = userManager; } // 登录 public async Task<SignInResult> LoginAsync(string username, string password, bool remember) { return await _signInManager.PasswordSignInAsync( username, password, remember, lockoutOnFailure: true); } // 注册+分配角色 public async Task<IdentityResult> RegisterAsync(AppUser user, string password) { var res = await _userManager.CreateAsync(user, password); if (res.Succeeded) await _userManager.AddToRoleAsync(user, "User"); return res; } // 退出登录 public async Task LogoutAsync() { await _signInManager.SignOutAsync(); } }3. 获取当前登录用户信息@inject AuthenticationStateProvider AuthStateProvider @inject UserManager<AppUser> UserManager @code { private AppUser? CurrentUser; protected override async Task OnInitializedAsync() { var state = await AuthStateProvider.GetAuthenticationStateAsync(); var user = state.User; if (user.Identity != null && user.Identity.IsAuthenticated) { CurrentUser = await UserManager.FindByNameAsync(user.Identity.Name); } } }七、BootstrapBlazor UI 组件库教程1. 必备基础组件BootstrapInput/BootstrapPassword:输入框、密码框(登录页)ValidateForm:表单校验ToastService:轻量弹窗提示(登录成功/失败)Card:卡片容器(登录布局)Dialog:弹窗窗口Table:数据表格(进销存、库存列表)2. Toast 弹窗使用前置条件:Program.cs 注册 AddBootstrapBlazor()App.razor 全局包裹 <BootstrapBlazorRoot>@inject ToastService Toast @code { // 成功提示 await Toast.Success("登录成功"); // 错误提示 await Toast.Error("账号密码错误"); }八、路由与页面跳转1. 页面路由声明@page "/login" @page "/user/list"2. 代码跳转 NavigationManager@inject NavigationManager Nav // 跳转首页 Nav.NavigateTo("/"); // 强制刷新页面(刷新登录认证状态) Nav.NavigateTo("/", forceLoad: true);九、分层架构(DDD,企业级规范)推荐四层标准结构:1. Domain.Abstractions - 接口定义 IAuthHelper - 数据库实体 AppUser 2. Application.Services - 业务逻辑实现 AuthHelper 3. Infrastructure - EF Core 数据库上下文 - 第三方接口对接 4. WebApp.Server - Blazor 页面、组件、布局 - Program 入口十、实战完整案例:登录功能@page "/login" @using BootstrapBlazor.Components @using System.ComponentModel.DataAnnotations @using BootstrapBlazorApp1.Server.Services @inject NavigationManager Nav @inject ToastService Toast @inject AuthHelper AuthHelper @layout TutorialsLoginLayout <div class="login-item login-item-gitee"> <div class="login-header"> <span>登录</span> </div> <ValidateForm Model="@LoginModel" OnValidSubmit="SubmitLogin"> <BootstrapInput TValue="string" @bind-Value="LoginModel.UserName" ShowLabel="false" PlaceHolder="请输入账号" IsAutoFocus="true" /> <BootstrapPassword TValue="string" @bind-Value="LoginModel.Password" ShowLabel="false" PlaceHolder="请输入密码" /> <Checkbox @bind-Checked="LoginModel.RememberMe" Text="记住我" /> <Button Text="登录" Color="Color.Primary" ButtonType="ButtonType.Submit" Class="mt-3 w-100"></Button> </ValidateForm> </div> @code { public class LoginDto { [Required(ErrorMessage = "请输入账号")] public string UserName { get; set; } = ""; [Required(ErrorMessage = "请输入密码")] public string Password { get; set; } = ""; public bool RememberMe { get; set; } } private LoginDto LoginModel { get; set; } = new(); private async Task SubmitLogin(EditContext context) { var result = await AuthHelper.LoginAsync( LoginModel.UserName, LoginModel.Password, LoginModel.RememberMe); if (result.Succeeded) { await Toast.Success("登录成功"); Nav.NavigateTo("/", true); } else if (result.IsLockedOut) { await Toast.Error("账号已锁定,请稍后重试"); } else { await Toast.Error("账号或密码错误"); } } }十一、官方学习文档(权威参考)微软官方 Blazor 文档: https://learn.microsoft.com/zh-cn/aspnet/core/blazor/BootstrapBlazor 官方文档: https://www.blazor.zone/docsBootstrapBlazor 在线演示: https://blazor.app1.es/十二、学习路线(循序渐进)阶段 1:基础语法Razor 语法双向绑定事件处理循环、条件渲染阶段 2:核心概念依赖注入生命周期方法(OnInitializedAsync)阶段 3:UI 组件库BootstrapBlazor 组件库表单校验Toast 弹窗阶段 4:身份认证Identity 身份认证登录/注册功能角色权限管理
2026年07月29日
3 阅读
0 评论
1 点赞
2026-07-28
Bootstrap Blazor 完整流程:注册 + 登录 + 身份验证 + 后台存数据带用户名
基于 BootstrapBlazor + ASP.NET Core Identity 实现,分 5 大块:环境配置、注册页面、登录页面、授权拦截、后台新增数据自动绑定当前登录用户。一、前置准备(项目开启 Identity)1.NuGet 安装包 <PackageReference Include="BootstrapBlazor" Version="最新版" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" /> 2.Program.cs 注册服务 var builder = WebApplication.CreateBuilder(args); // 1. 添加DbContext + Identity builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Default"))); // Identity 用户表,扩展自定义字段 builder.Services.AddDefaultIdentity<AppUser>(options => { // 密码规则 options.Password.RequireDigit = false; options.Password.RequiredLength = 6; options.Password.RequireNonAlphanumeric = false; }) .AddEntityFrameworkStores<AppDbContext>(); // 2. BootstrapBlazor builder.Services.AddBootstrapBlazor(); // 3. Blazor 组件 builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); var app = builder.Build(); // 认证授权中间件顺序不能乱 app.UseStaticFiles(); app.UseAuthentication(); // 登录Cookie app.UseAuthorization(); // 权限校验 app.UseAntiforgery(); app.MapRazorComponents<App>() .AddInteractiveServerRenderMode(); app.Run(); 自定义用户实体 AppUser.cs扩展需要的字段(手机号、昵称等),继承 IdentityUser using Microsoft.AspNetCore.Identity; public class AppUser : IdentityUser { // 可自定义扩展字段 public string NickName { get; set; } = ""; } 数据库上下文 AppDbContext.cs using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; public class AppDbContext : IdentityDbContext<AppUser> { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } // 业务表示例(后台需要保存的数据表) public DbSet<Product> Products { get; set; } } // 业务实体示例(每条数据记录创建人用户名) public class Product { public int Id { get; set; } public string Name { get; set; } = ""; public decimal Price { get; set; } // 关联登录用户名 public string CreateUserName { get; set; } = ""; public DateTime CreateTime { get; set; } = DateTime.Now; } 迁移数据库Add-Migration InitIdentity Update-Database自动生成:AspNetUsers、登录 / 角色相关表 + 业务 Product 表二、共享工具类:获取当前登录用户新建 AuthHelper.cs 全局获取登录用户名、IDusing Microsoft.AspNetCore.Components.Authorization; using System.Security.Claims; public static class AuthHelper { /// 获取当前登录用户名 public static async Task<string> GetUserNameAsync(AuthenticationStateProvider auth) { var state = await auth.GetAuthenticationStateAsync(); var user = state.User; if (!user.Identity.IsAuthenticated) return ""; return user.Identity.Name ?? ""; } /// 获取UserId public static async Task<string> GetUserIdAsync(AuthenticationStateProvider auth) { var state = await auth.GetAuthenticationStateAsync(); var user = state.User; return user.FindFirstValue(ClaimTypes.NameIdentifier) ?? ""; } /// 判断是否登录 public static async Task<bool> IsLoginAsync(AuthenticationStateProvider auth) { var state = await auth.GetAuthenticationStateAsync(); return state.User.Identity.IsAuthenticated; } } 三、注册页面 Register.razor(BootstrapBlazor 表单)路径 Pages/Account/Register.razor@page "/account/register"@inject UserManager UserManager@inject SignInManager SignInManager@inject NavigationManager Nav@inject ToastService Toast<Body> <EditForm Model="@model" OnValidSubmit="@RegisterSubmit"> <DataAnnotationsValidator /> <ValidationSummary /> <FormInput @bind-Value="model.UserName" Label="用户名" Placeholder="请输入用户名" /> <FormInput @bind-Value="model.Email" Label="邮箱" Placeholder="请输入邮箱" InputType="InputType.Email" /> <FormInput @bind-Value="model.Password" Label="密码" Placeholder="至少6位" InputType="InputType.Password" /> <FormInput @bind-Value="model.ConfirmPwd" Label="确认密码" InputType="InputType.Password" /> <Button Type="ButtonType.Submit" Color="Color.Primary" Class="mt-3">注册</Button> <a href="/account/login" class="ms-3">已有账号去登录</a> </EditForm> </Body>@code {private RegisterModel model = new(); private async Task RegisterSubmit() { if (model.Password != model.ConfirmPwd) { await Toast.Error("两次密码不一致"); return; } var user = new AppUser { UserName = model.UserName, Email = model.Email, NickName = model.UserName }; // 创建用户 var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { // 注册后自动登录 await SignInManager.SignInAsync(user, false); await Toast.Success("注册成功"); Nav.NavigateTo("/"); } else { var msg = string.Join(";", result.Errors.Select(e => e.Description)); await Toast.Error(msg); } } public class RegisterModel { [Required] public string UserName { get; set; } = ""; [Required, EmailAddress] public string Email { get; set; } = ""; [Required] public string Password { get; set; } = ""; public string ConfirmPwd { get; set; } = ""; }}四、登录页面 Login.razor(BootstrapBlazor)路径 Pages/Account/Login.razor@page "/account/login"@inject SignInManager SignInManager@inject NavigationManager Nav@inject ToastService Toast<Body> <EditForm Model="@loginModel" OnValidSubmit="@LoginSubmit"> <DataAnnotationsValidator /> <ValidationSummary /> <FormInput @bind-Value="loginModel.UserName" Label="用户名" /> <FormInput @bind-Value="loginModel.Password" Label="密码" InputType="InputType.Password" /> <Checkbox @bind-Value="loginModel.RememberMe" Label="记住登录" /> <Button Type="ButtonType.Submit" Color="Color.Primary" Class="mt-3">登录</Button> <a href="/account/register" class="ms-3">没有账号去注册</a> </EditForm> </Body>@code {private LoginModel loginModel = new(); private async Task LoginSubmit() { var result = await SignInManager.PasswordSignInAsync( loginModel.UserName, loginModel.Password, loginModel.RememberMe, lockoutOnFailure: false); if (result.Succeeded) { await Toast.Success("登录成功"); Nav.NavigateTo("/admin/product"); // 跳后台页面 } else { await Toast.Error("用户名或密码错误"); } } public class LoginModel { [Required] public string UserName { get; set; } = ""; [Required] public string Password { get; set; } = ""; public bool RememberMe { get; set; } }}五、全局授权拦截:未登录跳转登录App.razor 包裹路由,添加授权 <Found Context="routeData"> <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@MainLayout"> <NotAuthorized> @* 未登录自动跳转到登录页 *@ <RedirectToLogin /> </NotAuthorized> </AuthorizeRouteView> </Found> <NotFound> <PageNotFound /> </NotFound>新建 RedirectToLogin.razor@inject NavigationManager Nav@inject AuthenticationStateProvider Auth@code {protected override void OnInitialized() { Nav.NavigateTo("/account/login?returnUrl=" + Uri.EscapeDataString(Nav.ToBaseRelativePath(Nav.Uri))); }}后台页面添加 [Authorize] 限制访问@page "/admin/product"@attribute [Authorize] // 必须登录才能访问@inject AuthenticationStateProvider AuthProvider@inject AppDbContext Db@inject ToastService Toast六、后台页面:新增数据自动保存当前登录用户名后台商品管理页面 /Admin/Product.razor,新增时自动赋值 CreateUserName@page "/admin/product"@attribute [Authorize]@inject AuthenticationStateProvider AuthProvider@inject AppDbContext Db@inject ToastService Toast<Body> <Button Color="Color.Primary" OnClick="@OpenAddDialog">新增商品</Button> <Table TItems="@productList" Class="mt-3"> <TableColumn Field="p=>p.Id" Title="ID" /> <TableColumn Field="p=>p.Name" Title="商品名称" /> <TableColumn Field="p=>p.Price" Title="价格" /> <TableColumn Field="p=>p.CreateUserName" Title="创建人" /> <TableColumn Field="p=>p.CreateTime" Title="创建时间" /> </Table> </Body>@ 新增弹窗 @<FormInput @bind-Value="currentProduct.Name" Label="商品名称" /> <FormInput @bind-Value="currentProduct.Price" Label="价格" InputType="InputType.Number" />@code {private Dialog addDialog = new(); private List<Product> productList = new(); private Product currentProduct = new(); private string loginUserName = ""; protected override async Task OnInitializedAsync() { // 获取当前登录用户名 loginUserName = await AuthHelper.GetUserNameAsync(AuthProvider); await LoadData(); } // 加载列表 private async Task LoadData() { productList = await Db.Products.ToListAsync(); } // 打开新增弹窗 private void OpenAddDialog() { currentProduct = new(); addDialog.Show(); } // 保存数据,自动写入当前登录用户名 private async Task SaveProduct() { // 核心:自动绑定登录账号 currentProduct.CreateUserName = loginUserName; currentProduct.CreateTime = DateTime.Now; Db.Products.Add(currentProduct); await Db.SaveChangesAsync(); await Toast.Success("保存成功"); addDialog.Close(); await LoadData(); }}七、退出登录功能(布局顶部导航栏)在 MainLayout.razor 顶部导航增加退出按钮@inject SignInManager<AppUser> SignInManager@inject NavigationManager Nav@inject AuthenticationStateProvider AuthProvider @if (await AuthHelper.IsLoginAsync(AuthProvider)) { 退出登录 } else { 登录 注册 } @code {private async Task Logout() { await SignInManager.SignOutAsync(); Nav.NavigateTo("/account/login"); }}完整功能总结注册:Identity 创建用户,密码校验,注册自动登录登录:账号密码校验,Cookie 持久登录授权拦截:未登录自动跳转登录页,后台页面加 [Authorize]获取登录人:全局 AuthHelper 读取当前用户名保存数据:新增业务数据时自动赋值 CreateUserName 记录操作人界面全部使用 BootstrapBlazor 内置表单、弹窗、表格、提示组件退出登录清除身份 Cookie,跳转登录
2026年07月28日
7 阅读
0 评论
0 点赞
2026-07-28
BootstrapBlazor(Server)完整标准目录结构
结合 Identity 登录注册、后台业务、分层解耦、单人易维护设计,区分页面层、业务服务层、数据仓储、模型、公共工具、认证,适配你「注册 / 登录 / 权限 / 后台存数据带操作人」全套需求。 YourProject/ ├── Program.cs # 全局DI、认证、BB服务注册入口 ├── App.razor # 路由+全局授权拦截 ├── appsettings.json 数据库连接串、配置 ├── wwwroot/ 静态资源(css/js/图片) │ ├── Data/ 数据库&Identity核心 │ ├── AppDbContext.cs EF上下文(Identity+业务表) │ ├── Migrations/ EF迁移文件 │ ├── Entities/ 全部数据库实体 │ ├── Identity/ 扩展用户实体 │ │ └── AppUser.cs │ └── Business/ 业务表(商品/订单等) │ └── Product.cs │ ├── Models/ DTO、表单Model、视图模型 │ ├── Account/ 登录/注册表单模型 │ │ ├── LoginModel.cs │ │ └── RegisterModel.cs │ └── Dtos/ 接口传输DTO │ ├── Repositories/ 数据仓储层(解耦EF) │ ├── IProductRepo.cs │ └── ProductRepo.cs │ ├── Services/ 业务逻辑层(核心业务) │ ├── AccountService.cs 登录注册封装(可选,简化页面代码) │ └── ProductService.cs 商品增删改查业务 │ ├── Shared/ 全局共享组件、布局、工具 │ ├── MainLayout.razor 主布局(导航、退出按钮) │ ├── RedirectToLogin.razor 未登录跳转组件 │ ├── AuthHelper.cs 获取当前登录用户工具类 │ └── Components/ 通用弹窗、表格组件 │ ├── Pages/ 所有页面(路由页面) │ ├── Account/ 账号相关页面 │ │ ├── Login.razor │ │ └── Register.razor │ └── Admin/ 后台管理页面(需授权) │ └── Product.razor 商品管理(保存带创建人) └── obj / bin 编译缓存(忽略) 分层职责说明(单人开发清晰不混乱)Data 数据层(只管数据库)AppDbContext:包含 Identity 用户表 + 业务实体 DbSetMigrations:EF 自动生成迁移,不要手动修改职责:只定义表关系,不写业务逻辑Entities 实体层(数据库映射类)Entities/Identity/AppUser继承 IdentityUser,扩展昵称、手机号等自定义字段Entities/Business/Product业务表,包含 CreateUserName 创建人、创建时间等审计字段规范:只包含属性,无复杂业务方法(轻量实体,单人不用重型 DDD)Models 视图传输层(页面表单、返回对象)Account 文件夹:登录、注册页面绑定的表单类(LoginModel/RegisterModel)Dtos:列表查询返回、新增编辑专用传输对象,隔离数据库实体,避免泄露敏感字段Repositories 仓储层(隔离 EF Core)接口 + 实现分离,页面 / 服务不直接操作 DbContext示例:IProductRepo 定义查询、新增、修改接口ProductRepo 实现 DbContext 操作好处:后续换数据库、加缓存只改仓储,页面完全不动Services 业务层(所有业务规则放这里,页面轻量化)AccountService(可选推荐)封装注册、登录、退出、校验逻辑,页面只调用方法,不写大量 Identity 代码ProductService商品新增、编辑、删除、列表查询,自动注入仓储,自动携带当前操作人用户名页面只调用 _productService.SaveAsync(model, userName),不用重复写赋值逻辑Shared 共享公共资源MainLayout:全局侧边栏、顶部导航、登录 / 退出按钮RedirectToLogin:授权拦截跳转组件AuthHelper:静态工具,封装获取登录用户名、UserId、是否登录Shared/Components:全局复用弹窗、表格、搜索组件Pages 页面层(纯 UI,只做交互,不写复杂逻辑)Pages/Account 公开页面(无需 [Authorize])Login.razor/ Register.razor:登录注册表单,调用 AccountServicePages/Admin 后台私有页面(加 @attribute [Authorize])所有管理页面,仅调用 Service 获取数据,界面使用 BootstrapBlazor 组件(Table/Dialog/FormInput)页面原则:不写 EF、不写业务判断,只接收数据、弹窗、按钮事件适配你需求的分层优势(注册 + 登录 + 权限 + 保存带用户名)登录身份统一在 Shared/AuthHelper 获取,所有后台页面复用,无重复代码新增数据自动赋值用户名逻辑封装在 Service,每个后台页面不用重复写Identity 登录注册逻辑封装 AccountService,Login/Register 页面极简Admin 文件夹全部页面统一授权,结构清晰,一眼区分前台 / 后台仓储隔离数据库,后期加日志、数据过滤只需改 Repo,页面不动极简单人优化建议(不用过度分层)如果你是个人小型项目,不想拆 Repo+Service 两层,可以简化:简化目录(小型项目专用)删除 Repositories,Service 直接注入 DbContext,减少文件数量 YourProject/ ├── Data/ ├── Entities/ ├── Models/ ├── Services/ // Service直接操作DbContext,跳过仓储 ├── Shared/ └── Pages/ 适合:后台管理、个人工具、小型业务,开发更快,维护成本低路由规范约定账号页:/account/login / /account/register后台管理统一前缀 /admin/xxx,全部加授权标签所有页面统一放在 Pages 下,不零散丢根目录关键文件存放位置对应功能表格功能 对应目录文件用户注册 / 登录页面 Pages/Account获取当前登录账号 Shared/AuthHelper.cs用户数据库实体 Entities/Identity/AppUser.cs数据库上下文 Data/AppDbContext.cs商品等业务实体 Entities/Business后台商品管理页面 Pages/Admin商品增删业务逻辑 Services/ProductService全局布局、退出按钮 Shared/MainLayout未登录自动跳转 Shared/RedirectToLogin
2026年07月28日
7 阅读
0 评论
0 点赞
2026-07-27
Excel二维码标签插件 固定资产/设备铭牌/合格证批量生成工具支持Excel、WPS,一键批量生成千百个二维码、条形码标签
强大的二维码生成插件,千百二维码一键快速生成。固定资产标签、设备铭牌、产品合格证、产品出货标识卡等二维码标签一键生成!支持excel2010、2013、2016、2019,完美支持WPS。下载地址:Excel二维码标签插件一、多类型商用标签批量生成固定资产标签、设备铭牌、产品合格证、产品出货标识卡批量生成固定资产标签、设备铭牌、产品合格证、产品出货标识卡等二维码标签一键生成等功能。二、批量生成二维码千百个二维码,一键快速生成批量生成二维码功能,支持将多行信息批量生成二维码。生成过程可拼接标题、添加二维码白边、添加logo、给二维码添加文字、可将生成的二维码插入批注、导出生成的二维码并且以某一列关键字命名等功能。批量二维码效果三、批量生成条形码千百个条形码,一键快速生成批量生成条形码功能,支持将多行编码批量生成条码;自定义尺寸、留白、附加文字,支持图片导出与批注插入。
2026年07月27日
14 阅读
0 评论
1 点赞
2026-07-27
芯宇宙Excel仓库管理系统 三种数据库 | 三种网络部署模式
Excel+数据库进销存管理,支持扫码、多用户权限、自动报表系统简述本系统基于Excel+数据库开发,仅支持Windows系统,兼容Office 2007~2021、WPS办公软件。 一次性买断永久使用,无年费,免费售后升级。数据库版本区分Access版:Office用户单机使用SQLite版:WPS用户专用SQL Server版:局域网/互联网多用户联网协同提示:建议先下载单机版试用,满意后再购买联网授权。
2026年07月27日
37 阅读
0 评论
1 点赞