MapMiddleware 是当 Request.Path 匹配某一给定的内容时 需要执行给定操作的一个中间件。
调用的代码为:
public static IApplicationBuilder Map([NotNull] this IApplicationBuilder app, [NotNull] string pathMatch, [NotNull] Action<IApplicationBuilder> configuration)
{
return Map(app, new PathString(pathMatch), configuration);
}
具体使用的例子如:
//To gracefully shutdown the server - Not for production scenarios
app.Map("/shutdown", shutdown =>
{
shutdown.Run(async context =>
{
var appShutdown = context.ApplicationServices.GetService<IApplicationShutdown>();
appShutdown.RequestShutdown();
await Task.Delay(10 * 1000, appShutdown.ShutdownRequested);
if (appShutdown.ShutdownRequested.IsCancellationRequested)
{
await context.Response.WriteAsync("Shutting down gracefully");
}
else
{
await context.Response.WriteAsync("Shutting down token not fired");
}
});
---------Run 方法结束 此处调用了RunExtension 中的 Run([NotNull] this IApplicationBuilder app, [NotNull] RequestDelegate handler)
});
匹配的地址为:
www.testSite.com/shutdown
www.testSite.com/shutdown/testaction
不匹配如下地址: www.testSite.com/shutdown123
MapMiddleware 对应的RequestDelegate 代码如下:
public async Task Invoke([NotNull] HttpContext context)
{
PathString path = context.Request.Path;
PathString remainingPath;
if (path.StartsWithSegments(_options.PathMatch, out remainingPath))
{
// Update the path
PathString pathBase = context.Request.PathBase;
context.Request.PathBase = pathBase + _options.PathMatch;
context.Request.Path = remainingPath;
await _options.Branch(context);
context.Request.PathBase = pathBase;
context.Request.Path = path;
}
else
{
await _next(context);
}
}
另外:SignalR 中的代码:
public static IApplicationBuilder UseSignalR(this IApplicationBuilder builder)
{
return builder.UseSignalR("/signalr");
}
public static IApplicationBuilder UseSignalR(this IApplicationBuilder builder, string path)
{
return builder.Map(path, subApp => subApp.RunSignalR());
}
此处也调用了 Map 方法。
具体的Map实现代码:
public static IApplicationBuilder Map([NotNull] this IApplicationBuilder app, PathString pathMatch, [NotNull] Action<IApplicationBuilder> configuration)
{
if (pathMatch.HasValue && pathMatch.Value.EndsWith("/", StringComparison.Ordinal))
{
throw new ArgumentException("The path must not end with a '/'", "pathMatch");
}
// create branch
var branchBuilder = app.New();
configuration(branchBuilder);
var branch = branchBuilder.Build();
var options = new MapOptions()
{
Branch = branch,
PathMatch = pathMatch,
};
return app.Use(next => new MapMiddleware(next, options).Invoke);
}
上述代码中为什么要 create branch ? 为什么要修改PathBase? 这样可以实现嵌套Map:代码如下:
builder.Map("/route1", map =>
{
map.Map((string)"/subroute1", UseSuccess);
map.Run(NotImplemented);
});
浙公网安备 33010602011771号