【问题标题】:Can a Controller support a route with variable string parameters?控制器可以支持带有可变字符串参数的路由吗?
【发布时间】:2021-02-20 04:35:46
【问题描述】:

我要支持/route/param1、/route/param1/param2、/route/param1/param2/param3等路由。

现在我已经在我的控制器中为每个参数组合定义了一个路由:

    [Route("{path1}")]
    public async Task<IActionResult> Route1(string path1)
    {
        return await ParsePath(new[] { path1 });
    }

    [Route("{path1}/{path2}")]
    public async Task<IActionResult> Route2(string path1, string path2)
    {
        return await ParsePath(new[] { path1, path2 });
    }

这有两个主要缺点:

  • 目前我有 8 个这样的参数,所以我最多只能支持 8 个参数
  • 如果我想支持更多参数,这段代码不是很干

我更喜欢使用带有这种签名的方法:

    public async Task<IActionResult> RouteMultiple(params string[] paths)
    {
        return await ParsePath(queryString, paths);
    }

但这与Route 属性兼容吗?

【问题讨论】:

  • 嗨@CamiloTerevinto 感谢您的回复。我想使用带有 URL 中参数的 GET 端点,以便用户可以轻松更改它们并用于 SEO 目的
  • 中间件途径听起来很有趣,使用一些中间件是否可以清理此代码并支持所描述的路由?

标签: c# asp.net-core .net-core asp.net-core-mvc


【解决方案1】:

这个呢:

  [Route("{path1?}/{path2?}/{path3?}/{path4?}")]
public async Task<IActionResult> RouteMultiple(string path1, string path2, ... and so on)
    {
        return await ParsePath(new[] { path1, path2, ... and so on });
    }

它在 Postman 中工作。

【讨论】:

  • 谢谢!这看起来简单而有前途,我会尝试的:)
  • 谢谢。我很高兴能帮到你。如果有效,请不要忘记接受答案。
【解决方案2】:

无法在 Controller 操作中执行此操作,因为它们没有考虑到这些情况。但是,您可以跳出 MVC 世界,直接在所需路径上使用中间件。

您在哪里配置:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

为您的动态路线添加另一张地图:

app.UseEndpoints(endpoints =>
{
    endpoints.Map("Products/{**values}", DynamicPathMiddleware.InvokeAsync);
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

DynamicPathMiddleware.InvokeAsync 是一个非常简单的静态方法,如下所示:

public class DynamicPathMiddleware
{
    public static async Task InvokeAsync(HttpContext context)
    {
        var paths = context.Request.Path.Value.Substring("Products/".Length + 1).Split('/');
        // from the question's code
        await ParsePath(paths);

        // and write to the response with
        await context.Response.WriteAsync(JsonSerializer.Serialize(paths));
    }
}

使用上面的代码,转到 /Products/asd/123/asd 将返回 HTTP 200,正文为 ["asd", "123", "asd"]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 2019-06-30
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    • 2013-07-04
    • 2020-09-01
    相关资源
    最近更新 更多