Самый простой способ сделать это - ввести RewriteOptions
в контроллер, а затем добавить к нему правила, но RewriteOptions.Rules
не является поточно-ориентированным.
Вам нужно пользовательское правило и потокобезопасная коллекция. Примерно так должно работать:
Startup:
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>())));
// ...
}
ImageRewriteCollection:
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);
}
ImageRewriteRule:
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;
}
}
}
}
Контроллер:
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();
}