You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:55:01