kim*_*gro 2 middleware asp.net-core
在 aspnetcore 3.1 中制作 UI 中间件的推荐方法是什么?
我正在尝试重现诸如squashbuckle之类的中间件的功能,消费者可以导入NuGet包,然后将其注册为:
app.UseMyCustomMiddleUI(c =>
{
c.RoutePrefix = "custom/ui";
});
Run Code Online (Sandbox Code Playgroud)
然后导航到http://localhost:5000/custom/ui将提供捆绑在我的 NuGet 包中的资源。
具体来说,如何打包 css、js 甚至 razor 页面等资源,以便在注册中间件时将它们暴露在某个路径上?
建议使用中间件的人static files。在 NuGet 包的上下文中,它是如何工作的,在该包中,我不提供来自文件系统的文件,而是提供嵌入在程序集中的文件(我猜测)
基本上你需要添加一个StaticFileMiddleware带有路由前缀的。在您的情况下,该前缀将是/custom/ui. 然后,您可以使用中间件从包中提供静态文件。
您可以查看SwaggerUI 源代码以了解他们是如何做到的。
我根据您的情况稍微调整了他们的代码。它看起来像这样。
public class CustomUiMiddleware
{
private const string RoutePrefix = "custom/ui";
private readonly StaticFileMiddleware _staticFileMiddleware;
public CustomUiMiddleware(
RequestDelegate next,
IWebHostEnvironment hostingEnv,
ILoggerFactory loggerFactory)
{
_staticFileMiddleware = CreateStaticFileMiddleware(next, hostingEnv, loggerFactory);
}
public async Task Invoke(HttpContext httpContext)
{
var httpMethod = httpContext.Request.Method;
var path = httpContext.Request.Path.Value;
// If the RoutePrefix is requested (with or without trailing slash), redirect to index URL
if (httpMethod == "GET" && Regex.IsMatch(path, $"^/?{Regex.Escape(RoutePrefix)}/?$", RegexOptions.IgnoreCase))
{
var indexUrl = httpContext.Request.GetEncodedUrl().TrimEnd('/') + "/index.html";
RespondWithRedirect(httpContext.Response, indexUrl);
return;
}
// Serve the index.html file
if (httpMethod == "GET" && Regex.IsMatch(path, $"^/{Regex.Escape(RoutePrefix)}/?index.html$", RegexOptions.IgnoreCase))
{
await RespondWithIndexHtml(httpContext.Response);
return;
}
// Serve a static file or continue to the next middleware
await _staticFileMiddleware.Invoke(httpContext);
}
private StaticFileMiddleware CreateStaticFileMiddleware(
RequestDelegate next,
IWebHostEnvironment hostingEnv,
ILoggerFactory loggerFactory)
{
var staticFileOptions = new StaticFileOptions
{
RequestPath = $"/{RoutePrefix}",
FileProvider = new EmbeddedFileProvider(typeof(CustomUiMiddleware).GetTypeInfo().Assembly),
};
return new StaticFileMiddleware(next, hostingEnv, Options.Create(staticFileOptions), loggerFactory);
}
private void RespondWithRedirect(HttpResponse response, string location)
{
response.StatusCode = 301;
response.Headers["Location"] = location;
}
private async Task RespondWithIndexHtml(HttpResponse response)
{
response.StatusCode = 200;
response.ContentType = "text/html;charset=utf-8";
await using var stream = typeof(CustomUiMiddleware).GetTypeInfo().Assembly.GetManifestResourceStream(typeof(CustomUiMiddleware), "index.html") ?? throw new NullReferenceException();
var htmlBuilder = new StringBuilder(await new StreamReader(stream).ReadToEndAsync());
await response.WriteAsync(htmlBuilder.ToString(), Encoding.UTF8);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
403 次 |
| 最近记录: |