尝试通过中间件向ASP.NET Core MVC添加特殊端点。
在app.UseWhen
中,我需要解析请求URL。在Controller上下文中,MVC使用以下模板很好地提取userId
:
GET http://contoso.com/users/{userId}/addresses
如何在没有设置MVC Controller构造的中间件中干净地完成这项工作?
如果答案有助于确定地址是否符合此模式,则奖励积分。
我手边的所有东西都是DefaultHttpContext。
URL
解析在MVC
管道中发挥作用,而不是在ASP.NET Core
管道中发挥作用。
你可能想要考虑MVC
filters,它可以访问路由上下文。
您可以从中间件访问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没有任何映射。
基于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。