ASP.NET核心中间件和URL解析

时间:2019-03-15 18:20:32

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

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

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

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

如何在未设置MVC Controller构造的中间件中完全做到这一点?

奖金首先指出答案是否有助于弄清地址是否符合此模式。

我手上只有DefaultHttpContext

3 个答案:

答案 0 :(得分:0)

URL解析在MVC管道中进行,而不是在ASP.NET Core中进行。

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

答案 1 :(得分:0)

您可以从中间件访问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没有任何映射。

答案 2 :(得分:0)

基于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。