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

ASP.NET Core 6 gRPC客户端调用GetDiscount时遇RpcException错误排查

gRPC通信异常排查:Basket.Api调用Discount.gRPC的GetDiscount方法报错

Grpc.Core.RpcException: Status(StatusCode="Unknown", Detail="Exception was thrown by handler.")

堆栈跟踪

at Basket.Api.Services.DiscountGrpc.DiscountClientService.GetDiscount(String productName) in E:\Microservices\run-aspnetcore-microservices\EcommerceMicro\Basket.Api\Services\DiscountGrpc\DiscountClientService.cs:line 17  
at Basket.Api.Controllers.BasketController.UpdateBasket(ShoppingCart basket) in E:\Microservices\run-aspnetcore-microservices\EcommerceMicro\Basket.Api\Controllers\BasketController.cs:line 39  
at lambda_method23(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

相关代码片段

Proto文件定义

option csharp_namespace = "Discount.gRPC.Protos";

service DiscountProtoService {
    rpc GetDiscount(GetDiscountRequest) returns (CouponModel);
}

message GetDiscountRequest {
    string productName = 1;
}

message CouponModel {
    int32 id = 1;
    string productId=2;
    string productName = 3;
    string description = 4;
    int32 amount = 5;
}

Basket.Api客户端GetDiscount实现

private readonly DiscountProtoService.DiscountProtoServiceClient discountClientService;

public DiscountClientService(DiscountProtoService.DiscountProtoServiceClient discountClientService)
{
    this.discountClientService = discountClientService;
}

public async Task<CouponModel> GetDiscount(string productName)
{
    var discountRequest = new GetDiscountRequest { ProductName = productName };
    return await discountClientService.GetDiscountAsync(discountRequest);
}

Basket.Api服务注册(Program.cs)

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IGreeterClientService, GreeterClientService>();
builder.Services.AddScoped<IDiscountClientService, DiscountClientService>();
builder.Services.AddGrpcClient<Greeter.GreeterClient>(c => c.Address = new Uri(builder.Configuration["GrpcSettings:DiscountUrl"]));
builder.Services.AddGrpcClient<DiscountProtoService.DiscountProtoServiceClient>(c => c.Address = new Uri(builder.Configuration["GrpcSettings:DiscountUrl"]));
var app = builder.Build();

Discount.gRPC服务端GetDiscount实现

public override async Task<CouponModel> GetDiscount(GetDiscountRequest request, ServerCallContext context)
{
    var coupon = await repository.GetDiscount(request.ProductName);

    if (coupon == null)
    {
        throw new RpcException(new Status(StatusCode.NotFound, $"Discount with ProductName = {request.ProductName} not found."));
    }

    var couponModel = mapper.Map<CouponModel>(coupon);

    logger.LogInformation("Discount is retrieved for ProductName : {productName}, Amount : {amount}", request.ProductName, coupon.Amount);

    return await Task.FromResult(couponModel);
    //return await Task.FromResult(new CouponModel());
}

Discount.gRPC服务注册(Program.cs)

using Discount.gRPC.Mapper;
using Discount.gRPC.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddGrpc();
builder.Services.AddAutoMapper(typeof(DiscountProfile));
var app = builder.Build();

// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGrpcService<DiscountService>();

app.Run();

补充说明

已测试Discount.gRPC中的默认Greeter服务,客户端与服务端通信正常,可提供更多代码片段协助排查问题。


内容的提问来源于stack exchange,提问作者Quốc Phi Nguyễn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 22:47:11