.Net Core如何通过ActionFilter按属性特性给标记的请求参数赋值
方案解答
需求可行性说明
你的需求完全可以通过Action Filter实现,不需要拆分两套API。
具体实现步骤
- 首先确认你已经定义好参数标记特性:
[AttributeUsage(AttributeTargets.Parameter)] public class EmployeeIdAttribute : Attribute { }
- 实现自定义Action Filter,在接口执行前替换标记参数的值:
public class EmployeeIdBindingFilter : IAsyncActionFilter { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { // 管理员/经理角色直接保留原有传参 if (context.HttpContext.User.IsInRole("Manager") || context.HttpContext.User.IsInRole("Administrator")) { await next(); return; } // 从JWT的Claims中提取当前登录用户的employeeId,Claim类型替换为你实际存储的字段 var employeeIdClaim = context.HttpContext.User.FindFirst("employeeId"); if (employeeIdClaim == null || !long.TryParse(employeeIdClaim.Value, out var currentEmployeeId)) { context.Result = new UnauthorizedResult(); return; } // 筛选所有标记了[EmployeeId]特性的参数,批量替换值 var targetParams = context.ActionDescriptor.Parameters .Where(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(EmployeeIdAttribute))); foreach (var param in targetParams) { context.ActionArguments[param.Name] = currentEmployeeId; } await next(); } }
- 在Program.cs中全局注册Filter即可生效:
builder.Services.AddControllers(options => { options.Filters.Add<EmployeeIdBindingFilter>(); });
其他可选方案对比
- 模型绑定器实现:也可以自定义针对
[EmployeeId]特性的模型绑定器,从Claims中取值绑定,逻辑和Filter基本一致,更符合ASP.NET Core的参数绑定规范,但实现复杂度和最终效果和Filter没有明显差异,你可以按需选择。 - 拆分两套API:完全不建议该方案。两类用户的业务逻辑100%复用,仅参数取值逻辑有差异,拆分后后续需求迭代需要同步维护两套代码,维护成本直接翻倍,没有收益。
内容的提问来源于stack exchange,提问作者Ahmet Umut Aydin
相关产品推荐
相关产品推荐

