【问题标题】:ASP.NET Core Middleware and URL ParsingASP.NET Core 中间件和 URL 解析
【发布时间】:2019-03-15 18:20:32
【问题描述】:

尝试通过中间件向 ASP.NET Core MVC 添加特殊端点。

app.UseWhen 中,我需要解析请求 URL。在 Controller 上下文中,MVC 可以很好地使用以下模板提取 userId

GET http://contoso.com/users/{userId}/addresses

如何在没有设置 MVC 控制器构造的中间件中干净地完成这项工作?

如果答案有助于首先确定地址是否符合此模式,则加分。

我手头只有DefaultHttpContext

【问题讨论】:

标签: asp.net-mvc asp.net-core .net-core routing middleware


【解决方案1】:

基于Mark Vincze's blog的解决方案

此方法用于提取用户 id 并使用它...

    private static void AddAddressesRoute(IApplicationBuilder app, RouteBuilder builder)
    {
        builder.MapVerb(
            HttpMethod.Get.Method,
            "users/{userId}/addresses",
            async context =>
            {
                var routeData = context.GetRouteData();
                var userId = routeData.Values["userId"];

                // userId available from here
            }
        );
    }

应该从应用程序构建器扩展方法启动。

    public static IApplicationBuilder UseAddresses(
        this IApplicationBuilder app
    )
    {
        RouteBuilder builder = new RouteBuilder(app);

        AddAddressesRoute(app, builder);

        app.UseRouter(builder.Build());

        return app;
    }

成为一个中间件,可以像这样添加到 Startup.Configure 方法中:

    app.UseAddresses()

它甚至不会干扰如果路由不匹配仍会触发的 MVC。

【讨论】:

    【解决方案2】:

    URL 解析在MVC 管道中起作用,而不是在ASP.NET Core 之一中。

    您可能需要考虑使用MVC filters,它可以访问路由上下文。

    【讨论】:

    • 据我了解,过滤器应用在 MVC 应用程序的控制器中。我想了解这在中间件环境中有何帮助。
    • 这就是重点——在中间件上下文中路由是没有意义的,因为这部分处理应该发生在链的 MVC 部分。因此,您要么需要使用除 MVC 之外的也可以解析 URL 模板的东西,要么..您只是在尝试您在错误的地方或错误的方式 - 在这种情况下,您的架构很可能应该修改。
    • 如果所有端点都由同一个团队编码,甚至是同一个项目的一部分,我会同意你的看法。问题是,中间件端点是要被重用的抽象的一部分。它们不能成为控制器的一部分,甚至会包含在 nuget 包中。
    【解决方案3】:

    您可以从中间件访问 HttpContext 并从查询字符串中解析出键值对,但您不能通过键值访问路径参数。

    例如:

    您通过http://contoso.com/api/users/5?zip=90210 对以下控制器进行GET:

     // GET api/users/5
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        return "value";
    }
    

    自定义中间件:

    public class MyCustomMiddleware
    {
        public Task InvokeAsync(HttpContext context)
        {   
            // get full path from context request path
            var queryPath = context.Request.Path().ToString(); 
            // will return /api/users/5
    
            // get id from query string
            var queryStringId = context.Request.Query["zip"].ToString();
            // will return 90210
        }
    }
    

    从您的 Controller 参数到 HttpContext 之间没有任何映射。

    【讨论】:

    • 问题在于路径值,而不是查询字符串。
    猜你喜欢
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    相关资源
    最近更新 更多