Kje*_*sen 2 c# asp.net-mvc url-rewriting asp.net-core-mvc asp.net-core
为了创建调整大小图像的本地磁盘缓存,我试图弄清楚如何在运行时创建 URL 重写。
像这样的东西:
[Route("(images/{id}.jpg")]
public IActionResult ResizeImage(int id, int height, int width)
{
string webRoot = _env.ContentRootPath;
var file = System.IO.Path.Combine(webRoot, $"resizedimage{id}.jpg");
//Pseudocode:
UrlRewriter.DoMagic($"images/{id}.jpg?height={height}&width={width}", "/resizedimage{id}.jpg")
return File(file, "image/jpeg");
}
Run Code Online (Sandbox Code Playgroud)
客户端请求 /images/123.jpg?height=100&width=100 ...
我可以创建一个静态 url 重写,将 /images/123.jpg?height=100&width=100 重写为 /images/resizedimage.jpg(磁盘上调整大小的图像),绕过操作方法(大概)。
我怎样才能用上面的伪代码即时做同样的事情?
笔记:
我不关心第一个请求,它将命中 actionmethod 并通过文件结果(如上所示)提供图像,只关心对同一 url 的后续请求。
我知道在启动时创建动态 url 重写的方法,但不是运行时(这就是我要问的)
是的,我可以只返回到图像文件的重定向,这也非常有效 - 但它仍然是来自客户端的两个同步请求。
需要 ASP.Net Core 2+
最简单的方法是注入RewriteOptions
控制器,然后向它添加规则,但RewriteOptions.Rules
不是线程安全的。
您需要自定义规则和线程安全集合。这样的事情应该工作:
启动:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ImageRewriteCollection>();
// ...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseRewriter(new RewriteOptions().Add(new ImageRewriteRule(app.ApplicationServices.GetService<ImageRewriteCollection>())));
// ...
}
Run Code Online (Sandbox Code Playgroud)
图像重写集合:
public class ImageRewriteCollection
{
private ConcurrentDictionary<(int id, int width, int height), string> imageRewrites
= new ConcurrentDictionary<(int id, int width, int height), string>();
public bool TryAdd(int id, int width, int height, string path)
=> imageRewrites.TryAdd((id, width, height), path);
public bool TryGetValue(int id, int width, int height, out string path)
=> imageRewrites.TryGetValue((id, width, height), out path);
}
Run Code Online (Sandbox Code Playgroud)
图像重写规则:
public class ImageRewriteRule : IRule
{
private readonly ImageRewriteCollection rewriteCollection;
private readonly Regex pathRegex = new Regex("^/images/(\\d+).jpg");
public ImageRewriteRule(ImageRewriteCollection rewriteCollection)
{
this.rewriteCollection = rewriteCollection;
}
public void ApplyRule(RewriteContext context)
{
var request = context.HttpContext.Request;
var pathMatch = pathRegex.Match(request.Path.Value);
if (pathMatch.Success)
{
bool isValidPath = true;
int id = int.Parse(pathMatch.Groups[1].Value);
int width = 0;
int height = 0;
string widthQuery = request.Query["width"];
string heightQuery = request.Query["height"];
if (widthQuery == null || !int.TryParse(widthQuery, out width))
isValidPath = false;
if (heightQuery == null || !int.TryParse(heightQuery, out height))
isValidPath = false;
if (isValidPath && rewriteCollection.TryGetValue(id, width, height, out string path))
{
request.Path = path;
context.Result = RuleResult.SkipRemainingRules;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
控制器:
private readonly ImageRewriteCollection rewriteCollection;
public HomeController(ImageRewriteCollection rewriteCollection)
{
this.rewriteCollection = rewriteCollection;
}
[Route("images/{id}.jpg")]
public IActionResult ResizeImage(int id, int width, int height)
{
rewriteCollection.TryAdd(id, width, height, "/resizedimagepath...");
return File();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
685 次 |
最近记录: |