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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:53:19