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

ASP.NET Core 6 Web API如何通过URL参数而非路径值实现路由?

动态路由转发实现方案

需求说明

客户端仅能请求固定URL:http://exampleDomain.com/ControllerDemo/HubActions?ActionName={ActionName},需根据ActionName参数值,将请求路由至对应的/ControllerDemo/{ActionName}接口(如ActionName=ActionA则路由到/ControllerDemo/ActionA)。

实现方式

方式一:在目标Controller方法内转发(适用于ASP.NET Web API)

直接在ControllerDemoController的HubActions方法中,根据参数构造目标URL并转发请求:

public class ControllerDemoController : ApiController
{
    public async Task<HttpResponseMessage> HubActions(string actionName)
    {
        // 构造目标请求URL
        var targetUri = new Uri(Request.RequestUri.AbsoluteUri.Replace(
            "HubActions?ActionName=" + actionName, 
            actionName
        ));
        
        // 创建转发请求并发送
        var forwardRequest = new HttpRequestMessage(Request.Method, targetUri);
        return await Configuration.Services.GetHttpClient().SendAsync(forwardRequest);
    }
}

方式二:自定义路由约束(ASP.NET Web API优雅方案)

通过自定义路由约束,在路由层面直接将请求导向目标Action,无需在方法内写转发逻辑:

  1. 配置自定义路由(WebApiConfig.cs):
public static void Register(HttpConfiguration config)
{
    // 匹配HubActions请求的自定义路由
    config.Routes.MapHttpRoute(
        name: "HubActionRoute",
        routeTemplate: "ControllerDemo/HubActions",
        defaults: new { controller = "ControllerDemo", action = "HubActions" },
        constraints: new { actionName = new HubActionRouteConstraint() }
    );

    // 常规API路由
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "{controller}/{action}",
        defaults: new { id = RouteParameter.Optional }
    );
}
  1. 实现自定义路由约束类:
public class HubActionRouteConstraint : IHttpRouteConstraint
{
    public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
    {
        if (routeDirection != HttpRouteDirection.UriResolution) return false;
        
        // 从Query参数中提取ActionName
        var actionName = request.GetQueryNameValuePairs()
            .FirstOrDefault(p => p.Key.Equals("ActionName", StringComparison.OrdinalIgnoreCase))
            .Value;
            
        if (!string.IsNullOrWhiteSpace(actionName))
        {
            // 替换路由的Action值为目标ActionName
            values["action"] = actionName;
            return true;
        }
        return false;
    }
}

方式三:ASP.NET Core中间件实现

在ASP.NET Core中,可通过中间件拦截请求并修改路径,实现路由转发:

  1. 编写中间件类:
public class HubActionMiddleware
{
    private readonly RequestDelegate _next;

    public HubActionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var request = context.Request;
        // 匹配固定请求路径
        if (request.Path.Equals("/ControllerDemo/HubActions", StringComparison.OrdinalIgnoreCase))
        {
            var actionName = request.Query["ActionName"].FirstOrDefault();
            if (!string.IsNullOrWhiteSpace(actionName))
            {
                // 修改请求路径为目标Action路径
                request.Path = $"/ControllerDemo/{actionName}";
            }
        }
        // 传递请求到下一个中间件
        await _next(context);
    }
}
  1. 在Program.cs中注册中间件:
var app = builder.Build();

// 注册自定义中间件(需放在路由中间件之前)
app.UseMiddleware<HubActionMiddleware>();

app.MapControllers();
app.Run();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:57:44