Мне пришлось искать код RewriteRule
, чтобы найти ответ. Вот фрагмент метода ApplyRule
:
PathString path1 = context.HttpContext.Request.Path;
Match match = path1 != PathString.Empty ? this.InitialMatch.Match(path1.ToString().Substring(1)) : this.InitialMatch.Match(path1.ToString());
if (!match.Success)
return;
context.HttpContext.Request.Path
возвращает только /quote_request.aspx
для запроса на quote_request.aspx?id=123
, в то время как отсутствующая часть находится в context.HttpContext.Request.QueryString
! Поэтому он просто игнорирует часть URL после ?
и не применяет правило, даже если переданное регулярное выражение корректно. Поэтому, чтобы избежать пропуска запроса, вы должны написать собственный IRule
на основе существующего класса RewriteRule
, вот упрощенный пример:
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite;
public class CustomRewriteRule : IRule
{
public Regex InitialMatch { get; }
public string Replacement { get; }
public bool StopProcessing { get; }
public CustomRewriteRule(string regex, string replacement, bool stopProcessing)
{
InitialMatch = new Regex(regex, RegexOptions.Compiled | RegexOptions.CultureInvariant);
Replacement = replacement;
StopProcessing = stopProcessing;
}
public virtual void ApplyRule(RewriteContext context)
{
var fullPath = context.HttpContext.Request.Path + context.HttpContext.Request.QueryString;
var match = fullPath != string.Empty ? InitialMatch.Match(fullPath.Substring(1)) : InitialMatch.Match(fullPath);
if (!match.Success)
return;
var str = match.Result(this.Replacement);
var request = context.HttpContext.Request;
if (StopProcessing)
context.Result = RuleResult.SkipRemainingRules;
request.Path = str[0] != '/' ? PathString.FromUriComponent("/" + str) : PathString.FromUriComponent(str);
request.QueryString = QueryString.Empty;
}
}
Использование:
var options = new RewriteOptions().Add(new CustomRewriteRule(@"^(?i)quote_request.aspx\?id=(.*)", "quote/revise/$1", true));
app.UseRewriter(options);