ASP.NET中如何获取gRPC方法的自定义特性
在gRPC拦截器中获取方法的自定义特性
核心问题
gRPC拦截器里的context.Method返回的是proto定义的方法全路径(比如/MyService/ServerStatus),无法直接关联到C#服务类中的具体方法,因此需要提前构建两者的映射关系。
解决方案步骤
1. 构建Proto方法名到C# MethodInfo的映射
在应用启动时,通过反射扫描你的gRPC服务实现类,提取每个方法的GrpcMethodAttribute信息,构建proto方法路径与C#方法的映射字典:
// 全局或拦截器类中定义映射字典 private readonly Dictionary<string, MethodInfo> _grpcMethodMap; private readonly ILogger<MyGrpcInterceptor> _logger; // 在拦截器构造时初始化映射 public MyGrpcInterceptor(ILogger<MyGrpcInterceptor> logger) { _logger = logger; _grpcMethodMap = BuildGrpcMethodMap(typeof(MyGrpcService)); // 替换为你的gRPC服务实现类类型 } private Dictionary<string, MethodInfo> BuildGrpcMethodMap(Type serviceType) { var methodMap = new Dictionary<string, MethodInfo>(); var methods = serviceType.GetMethods(BindingFlags.Public | BindingFlags.Instance); foreach (var method in methods) { var grpcAttr = method.GetCustomAttribute<GrpcMethodAttribute>(); if (grpcAttr == null) continue; // 拼接proto标准的方法全路径 var fullMethodPath = $"/{grpcAttr.ServiceName}/{grpcAttr.MethodName}"; methodMap[fullMethodPath] = method; } return methodMap; }
2. 在拦截器中获取方法特性并执行逻辑
在UnaryServerHandler中,通过context.Method从映射字典中拿到对应的MethodInfo,然后读取自定义特性:
public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>( TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation) { if (_grpcMethodMap.TryGetValue(context.Method, out var targetMethod)) { // 获取自定义特性 var authorizedAttr = targetMethod.GetCustomAttribute<AuthorizedUserAttribute>(); if (authorizedAttr != null) { // 这里执行你的自定义逻辑,比如权限验证、日志增强等 _logger.LogInformation($"Accessing authorized method: {targetMethod.Name}"); } } try { return await continuation(request, context); } catch (Exception ex) { _logger.LogError(ex, $"Error thrown by {context.Method}."); throw; } }
补充说明
- 如果项目中有多个gRPC服务类,可以在
BuildGrpcMethodMap中批量扫描所有服务类型(比如通过程序集反射查找继承自BindableService的类)。 - 该方案基于反射初始化映射,只会在应用启动时执行一次,不会影响运行时性能。
内容的提问来源于stack exchange,提问作者NewProger
相关产品推荐
相关产品推荐

