ASP.NET 核心中间件和 URL 解析
ASP.NET Core Middleware and URL Parsing
尝试通过中间件向 ASP.NET 核心 MVC 添加特殊端点。
在app.UseWhen
中,我需要解析请求URL。在 Controller 上下文中,MVC 使用以下模板很好地提取 userId
:
GET http://contoso.com/users/{userId}/addresses
如何在未设置 MVC 控制器构造的中间件中干净地完成此操作?
如果答案有助于首先确定地址是否符合此模式,则加分。
我手头只有一个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
}
}
没有从您的控制器参数到 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。
尝试通过中间件向 ASP.NET 核心 MVC 添加特殊端点。
在app.UseWhen
中,我需要解析请求URL。在 Controller 上下文中,MVC 使用以下模板很好地提取 userId
:
GET http://contoso.com/users/{userId}/addresses
如何在未设置 MVC 控制器构造的中间件中干净地完成此操作?
如果答案有助于首先确定地址是否符合此模式,则加分。
我手头只有一个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
}
}
没有从您的控制器参数到 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。