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

如何从Program.cs将带动态路由的GET请求转发到自定义控制器?

问题描述

希望通过如下动态URL访问控制器方法:

http://127.0.0.1:4567/api/img/get/stuff/1/0/45/strings/numbers/andallkindsofstuff/2

其中仅api/img/get为静态路由部分,后续所有内容均为动态参数。需要将所有以api/img/get开头的GET请求路由到对应控制器方法,该方法用于生成并返回图片。

现有代码片段如下:

Program.cs 部分代码

// 业务逻辑已移除
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Use(async (context, next) =>
{
    if (!MyCache.Ready) return; // 正常忽略请求

    // new CustomController().Get(content.Request.Path)

    await next(); // 调用控制器
});
app.UseMvc();
app.UseAuthorization();
app.MapControllers();
app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

ImageController 代码

[Route("api/img")]
[ApiController]
public class ImageController : ControllerBase
{
    [HttpGet]
    [Route("get")]
    public byte[] Get([FromQuery] string parameters)
    {
        // ...
    }
}

解决方案

方案一:修改控制器路由(推荐,原生路由支持)

无需额外中间件,直接通过路由属性的通配符*捕获api/img/get之后的所有路径内容:

[Route("api/img")]
[ApiController]
public class ImageController : ControllerBase
{
    // 用 * 捕获get之后的完整路径参数
    [HttpGet("get/{*parameters}")]
    public byte[] Get(string parameters)
    {
        // parameters 会自动获取到 stuff/1/0/45/strings/numbers/andallkindsofstuff/2
        // 此处可拆分、解析参数并生成图片
        return new byte[0]; // 返回生成的图片字节数组
    }
}

配置完成后,所有以api/img/get/开头的GET请求都会自动匹配到该方法,无需额外中间件处理。

方案二:使用中间件手动路由调用控制器

如果必须通过中间件实现,可通过DI容器解析控制器实例,避免直接new导致依赖注入失效:

修改Program.cs中的中间件逻辑:

app.Use(async (context, next) =>
{
    if (!MyCache.Ready) return;

    var path = context.Request.Path.Value;
    // 判断是否为目标GET请求
    if (context.Request.Method == HttpMethods.Get 
        && path.StartsWith("/api/img/get", StringComparison.OrdinalIgnoreCase))
    {
        // 从DI容器获取控制器实例
        var imageController = context.RequestServices.GetRequiredService<ImageController>();
        // 提取get之后的参数部分
        var parameters = path["/api/img/get".Length..].TrimStart('/');
        // 调用方法获取图片字节
        var imageBytes = imageController.Get(parameters);
        
        // 设置响应头并返回图片
        context.Response.ContentType = "image/png"; // 根据实际图片类型调整
        await context.Response.Body.WriteAsync(imageBytes);
        return; // 终止后续中间件流程
    }

    await next(); // 其他请求走正常路由流程
});

同时需确保控制器及依赖被注册到DI容器:

// 在builder.Build()之前添加
builder.Services.AddControllers();
// 若ImageController有构造函数依赖,需同步注册对应服务

内容的提问来源于stack exchange,提问作者Bitterblue

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:45:39