Grpc.AspNetCore 是推荐的服务端宿主方案,关键在 Program.cs 路由顺序、.proto 的 <Protobuf> 声明(GrpcServices="Server"/"Client")、显式引用 Grpc.Tools、服务继承 GreeterBase 且重写方法、Channel 凭证配置及避免混用 Grpc.Core 与 Grpc.Net.Client。

Grpc.AspNetCore 是当前 .NET 生态中推荐的服务端宿主方案,但直接套用模板容易在 Program.cs、.proto 引用方式、生成代码位置这几个地方出错。核心不是“能不能跑”,而是“为什么一改就报 RpcException: Status(StatusCode=Unimplemented 或 Could not load file or assembly 'Grpc.Core'”。
怎么让 .proto 文件正确生成服务基类和消息类
关键不在写法,而在项目文件里的 <Protobuf> 声明是否匹配目标框架和用途。
-
GrpcDemo.Protocol类库项目必须显式添加Grpc.Tools包(不能只靠Grpc.AspNetCore间接引用) - 服务端项目(如 ASP.NET Core)的
<Protobuf>项里GrpcServices="Server"才会生成GreeterBase;客户端项目必须设为"Client",否则GreeterClient类不会出现 -
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />中的路径是相对于项目根目录的,不是解决方案根目录——放错位置会导致生成失败且无提示 - 生成的
*.Grpc.cs和*.pb.cs文件默认在obj/下,不显示在解决方案资源管理器中,别手动添加或签入
服务端注册时为什么 MapGrpcService<T>() 不生效
常见于 ASP.NET Core 项目启动失败或调用返回 UNIMPLEMENTED。这不是路由问题,而是生命周期或依赖注入链断裂。
- 确保
app.MapGrpcService<GreeterService>();放在app.UseRouting()之后、app.UseEndpoints(...)之前(.NET 6+ 的 Minimal Hosting 模式下顺序更敏感) -
GreeterService必须继承自GreeterBase,且重写方法签名完全一致(包括ServerCallContext参数),少一个override就触发基类的throw new RpcException(...) - 如果服务依赖其他
IService(比如数据库上下文),需在Program.cs中提前注册,否则运行时解析失败,日志里只有InvalidOperationException: No service for type... - HTTP/2 是 gRPC 硬性要求,Kestrel 默认启用,但若反向代理(如 Nginx)没配好
http2和upgrade头,客户端会静默失败
客户端调用时连不上或超时,Channel 怎么配才对
错误常表现为 Status(StatusCode=DeadlineExceeded 或 Unable to connect to the remote server,根源多在传输层配置而非业务逻辑。
- 不要用
new Channel("localhost:5001", ...)直连——.NET 8+ 已弃用无凭证构造函数;必须显式传Credentials.Insecure(开发时)或Credentials.SecureSsl(生产) - HTTPS + gRPC 要求 TLS 1.2+ 且服务器证书可验证;本地开发用
https://localhost:5001时,客户端需加ChannelOption.SslTargetNameOverride绕过主机名校验 - 高频短连接场景下,
Channel应作为单例复用,而不是每次调用都new——否则会快速耗尽端口或触发连接池限流 - 调试时可用
GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions { HttpHandler = new SocketsHttpHandler { ConnectTimeout = TimeSpan.FromSeconds(5) } })控制底层超时
为什么 Grpc.Core 和 Grpc.Net.Client 不能混用
这是跨版本迁移中最隐蔽的坑:两个包的底层通道、线程模型、TLS 实现完全不同,混用会导致 DllNotFoundException 或随机 ObjectDisposedException。
-
Grpc.AspNetCore(服务端) +Grpc.Net.Client(客户端) 是官方推荐组合,全部基于System.Net.Http -
Grpc.Core是旧版 C-core 封装,依赖原生grpc_csharp_ext.x64.dll,Windows 上需额外分发该 DLL,Linux/macOS 需预装 libgrpc - 若项目同时引用了
Google.Protobufv3 和 v4,生成的*.pb.cs会因序列化器不兼容而抛InvalidProtocolBufferException - 检查
dotnet list package输出,确认没有Grpc.Core或Grpc.Core.Api的残留引用——哪怕只是间接依赖
GrpcServices 属性值写错、Channel 凭证漏配、或者以为 obj/ 下生成的代码能手动改——它每次构建都会覆盖,改了也白改。


















