背景:在大量地图瓦片的请求过程中,可能存在瓦片遗失的情况,这时候需要在地图上展示默认的瓦片图片,之前在前端相关地图包中去实现,现在在后台实现当请求瓦片失败时,返回默认的瓦片图片,且支持默认图片配置。
解决:
1.创建.net 5 Web项目
2.引入Microsoft.Extensions.Configuration,用于读取appsettings.json
3.新建中间件类DefaultImageMiddleware
public class DefaultImageMiddleware
{
private readonly RequestDelegate _next;
public static string DefaultImagePath { get; set; }
/// <summary>
/// 管道执行达到我们的中间件的时候从上一个中间件接收到RequestDelegate委托
/// </summary>
/// <param name="next"></param>
/// <param name="defaultImagePath">默认瓦片图片</param>
public DefaultImageMiddleware(RequestDelegate next, string defaultImagePath)
{
this._next = next;
DefaultImagePath = defaultImagePath;
}
/// <summary>
/// 给HTTP请求管道加入业务进去
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task Invoke(HttpContext context)
{
await _next(context);//将context传递给下一个中间件
if (context.Response.StatusCode == 404)
{//请求资源404
var contentType = context.Request.Headers["accept"].ToString().ToLower();
await SetDefaultImage(context);
if (contentType.StartsWith("image"))
{
await SetDefaultImage(context);
}
}
}
/// <summary>
/// 返回默认图片
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private async Task SetDefaultImage(HttpContext context)
{
try
{
string path = Path.Combine(Directory.GetCurrentDirectory(), DefaultImagePath);
FileStream fs = File.OpenRead(path);
byte[] bytes = new byte[fs.Length];
await fs.ReadAsync(bytes, 0, bytes.Length);
await context.Response.Body.WriteAsync(bytes, 0, bytes.Length);
}
catch (Exception ex)
{
await context.Response.WriteAsync(ex.Message);
}
}
}
注意:自定义中间件类中必须要有构造函数和Invoke方法,前者是接受下一个中间件委托;后者是你的中间件业务实现部分;
4.在Startup.cs中Configure注册自定义中间件
public class Startup
{
/// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseStaticFiles();
string url = Configuration["defaultImagePath"];
app.UseMiddleware<DefaultImageMiddleware>(url);//注册返回默认图片的中间件
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
});
}
}
5.在appsettings.json中添加相关配置
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"defaultImagePath": "wwwroot\\default.jpg"//默认瓦片图片路径
}
这样在请求图片404时,就可以返回指定的默认图片了