如何在ASP.NET Core WebAPI中用自定义属性复用用户校验逻辑?
在ASP.NET Core WebAPI中用自定义属性复用用户检查逻辑
完全可以通过自定义Action过滤器属性实现这个需求,把重复的用户名获取、检查逻辑封装起来,通过[CheckUser]属性标注到需要的端点上即可。以下是具体实现步骤:
1. 创建自定义CheckUser过滤器
继承ActionFilterAttribute,重写OnActionExecuting方法,在这里统一处理用户名的获取与检查逻辑:
using Microsoft.AspNetCore.Mvc.Filters; public class CheckUserAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { // 获取当前登录用户的用户名 var userName = context.HttpContext.User.Identity?.Name; // 基础检查:如果用户名为空,直接返回未授权 if (string.IsNullOrEmpty(userName)) { context.Result = new UnauthorizedResult(); return; } // 这里可以添加通用的用户名相关操作,比如: // - 验证用户是否存在于数据库 // - 加载用户的额外信息存入HttpContext // - 记录用户访问日志等 // 将用户名存入HttpContext.Items,方便后续接口直接使用 context.HttpContext.Items["CurrentUserName"] = userName; base.OnActionExecuting(context); } }
2. 在端点上使用自定义属性
直接在需要的API方法上标注[CheckUser],过滤器会在接口执行前自动处理逻辑:
[HttpGet] [CheckUser] public IActionResult EndPoint1() { // 从HttpContext.Items中获取预处理好的用户名 var userName = HttpContext.Items["CurrentUserName"] as string; // 执行Endpoint1的专属业务逻辑 return Ok($"Endpoint1:当前用户为 {userName}"); } [HttpGet] [CheckUser] public IActionResult EndPoint2() { var userName = HttpContext.Items["CurrentUserName"] as string; // 执行Endpoint2的专属业务逻辑 return Ok($"Endpoint2:当前用户为 {userName}"); }
3. 进阶:依赖注入支持
如果你的用户名相关操作需要依赖其他服务(比如数据库上下文),可以通过构造注入实现:
改造过滤器类
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.EntityFrameworkCore; public class CheckUserAttribute : ActionFilterAttribute { private readonly ApplicationDbContext _dbContext; // 通过构造函数注入数据库上下文 public CheckUserAttribute(ApplicationDbContext dbContext) { _dbContext = dbContext; } public override async Task OnActionExecutingAsync(ActionExecutingContext context) { var userName = context.HttpContext.User.Identity?.Name; if (string.IsNullOrEmpty(userName)) { context.Result = new UnauthorizedResult(); return; } // 示例:检查用户是否存在于数据库 var userExists = await _dbContext.Users.AnyAsync(u => u.UserName == userName); if (!userExists) { context.Result = new NotFoundObjectResult("用户不存在"); return; } context.HttpContext.Items["CurrentUserName"] = userName; await base.OnActionExecutingAsync(context); } }
注册过滤器为服务
在Program.cs中注册该过滤器:
builder.Services.AddScoped<CheckUserAttribute>();
在接口中使用ServiceFilter
因为需要注入依赖,此时要改用[ServiceFilter]标注:
[HttpGet] [ServiceFilter(typeof(CheckUserAttribute))] public IActionResult EndPoint1() { var userName = HttpContext.Items["CurrentUserName"] as string; // 业务逻辑... return Ok(userName); }
这种方式既实现了代码复用,又能灵活扩展通用逻辑,完全符合你的需求。
内容的提问来源于stack exchange,提问作者QasemBSK
相关产品推荐
相关产品推荐

