Dapr自定义中间件C#实现、注册及跨微服务使用全流程求助
Dapr自定义中间件端到端实现指南(C#/.NET)
一、核心概念澄清
首先明确Dapr的两种中间件类型:
- 应用级中间件:嵌入ASP.NET Core请求管道,仅处理直接发送到应用的请求(含Dapr Sidecar转发的请求)
- Sidecar级中间件:通过YAML配置注册到Dapr Sidecar,作用于所有经过Sidecar的请求(包括跨微服务调用)
你当前编写的是应用级中间件,若要实现跨服务调用时生效的全局中间件,需配置Sidecar级中间件。
二、应用级中间件的修正与验证
1. 修正Startup配置
调整中间件在ASP.NET管道中的位置,确保正确处理Dapr转发的请求:
public class Startup { public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; } public void ConfigureServices(IServiceCollection services) { services.AddDaprClient(); // 必须添加,用于跨服务调用 services.AddTransient<DaprCustomAuthMiddleware>(); services.AddControllers().AddDapr(); // 推荐添加,简化Dapr请求处理 services.AddSingleton(new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, PropertyNameCaseInsensitive = true, }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseCloudEvents(); // 优先处理Dapr CloudEvents格式请求 app.UseMiddleware<DaprCustomAuthMiddleware>(); // 应用自定义中间件 app.UseEndpoints(endpoints => { endpoints.MapSubscribeHandler(); // 使用官方订阅处理器,替代自定义实现 endpoints.MapControllers(); endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Service is running"); }); }); } }
2. 验证应用级中间件
启动服务:
dapr run --app-id my-service --app-port 5000 --dapr-http-port 3500 dotnet run
调用服务测试:
curl http://localhost:3500/v1.0/invoke/my-service/method/
此时控制台会输出中间件的日志,说明应用级中间件生效。
三、Sidecar级中间件的注册与配置(跨服务调用生效)
1. 创建Sidecar中间件类库
新建.NET类库项目,实现中间件逻辑:
using Microsoft.AspNetCore.Http; using System.Threading.Tasks; namespace DaprCustomMiddleware { public class CustomAuthMiddleware { private readonly RequestDelegate _next; public CustomAuthMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"[Sidecar Middleware] Incoming request: {context.Request.Path}"); await _next(context); Console.WriteLine($"[Sidecar Middleware] Outgoing response: {context.Response.StatusCode}"); Console.ResetColor(); } } // 扩展类用于注册中间件 public static class CustomAuthMiddlewareExtensions { public static IApplicationBuilder UseCustomAuthMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<CustomAuthMiddleware>(); } } }
将类库打包为NuGet包(或直接项目引用到服务中)。
2. 编写Dapr中间件组件YAML
创建components/custom-auth-middleware.yaml:
apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: custom-auth-middleware spec: type: middleware.http version: v1 metadata: - name: appPort value: "5000" # 你的应用监听端口 - name: middlewarePath value: "/middleware/custom-auth" # 中间件暴露的端点路径
3. 配置Dapr Sidecar使用中间件
创建dapr/config.yaml,将中间件加入请求管道:
apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: dapr-config spec: httpPipeline: handlers: - name: custom-auth-middleware type: middleware.http
4. 在服务中暴露中间件端点
修改Startup.cs,添加中间件路由:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // ...其他配置 app.UseEndpoints(endpoints => { // ...其他端点 endpoints.Map("/middleware/custom-auth", appBuilder => { appBuilder.UseCustomAuthMiddleware(); // 绑定Sidecar中间件 }); }); }
四、跨微服务调用验证
1. 启动两个测试服务
- 服务A(my-service):
dapr run --app-id my-service --app-port 5000 --dapr-http-port 3500 --config dapr/config.yaml dotnet run
- 服务B(another-service):
dapr run --app-id another-service --app-port 5001 --dapr-http-port 3501 --config dapr/config.yaml dotnet run
2. 在服务B中添加跨服务调用代码
创建控制器实现调用逻辑:
using Dapr.Client; using Microsoft.AspNetCore.Mvc; [ApiController] [Route("test")] public class TestController : ControllerBase { private readonly DaprClient _daprClient; public TestController(DaprClient daprClient) { _daprClient = daprClient; } [HttpGet("call-service-a")] public async Task<IActionResult> CallServiceA() { var result = await _daprClient.InvokeMethodAsync<string>(HttpMethod.Get, "my-service", "/"); return Ok(result); } }
3. 验证中间件生效
调用服务B的端点触发跨服务调用:
curl http://localhost:3501/v1.0/invoke/another-service/method/test/call-service-a
此时服务A的控制台会输出Sidecar中间件的日志,说明跨服务调用时中间件已生效。
五、常见问题排查
- 应用级中间件不生效:检查中间件在ASP.NET管道中的位置,确保在
UseCloudEvents之后、UseEndpoints之前 - Sidecar级中间件不生效:核对YAML配置的
appPort和middlewarePath是否正确,确认服务已暴露对应端点 - 跨服务调用失败:确保两个服务的Dapr app-id唯一,Sidecar端口无冲突
内容的提问来源于stack exchange,提问作者Jitender Singal
相关产品推荐
相关产品推荐

