无法重写包含查询字符串组件的 URL
Can't rewrite a URL including the query string components
我正在尝试在 asp.net 核心 2.2 中做一些 URL 重写,但它似乎不适用于查询字符串部分。我想将 "finditem?txn=3" 之类的任何路径更改为 "find/item?transactionid=3" 之类的路径。作为一个更简单的例子,没有智能替换 transactionID,看这段代码:
private static RewriteOptions GetRewriteOptions() => new RewriteOptions()
.AddRewrite(@"^bananatxn=\d$", "Download", true) // Works with bananatxn=1
.AddRewrite(@"^banana\?txn=\d$", "Download", true); // Does NOT work with banana?txn=1
为什么重写器无法匹配问号字符?我已经在 http://regexstorm.net/tester 中测试了我的模式,虽然模式似乎是正确的,但它不起作用。 asp.net 核心中的重写器可以重写整个 URL,包括查询字符串,还是只重写问号之前的部分?
我已经调查并认为(但不确定)此功能在 asp.net 核心提供的内置规则中不可用。这对我有用。绝对没有经过彻底测试,可能过于重视大小写,而且我对所有 URL 组件和格式都不太熟悉。
public class RewritePathAndQuery : IRule
{
private Regex _regex;
private readonly string _replacement;
private readonly RuleResult _resultIfRewrite;
/// <param name="regex">Pattern for the path and query, excluding the initial forward slash.</param>
public RewritePathAndQuery(string regex, string replacement, bool skipRemainingRules)
{
_regex = new Regex(regex);
_replacement = replacement;
_resultIfRewrite = skipRemainingRules ? RuleResult.SkipRemainingRules : RuleResult.ContinueRules;
}
public void ApplyRule(RewriteContext context)
{
HttpRequest request = context.HttpContext.Request;
string pathExcludingInitialForwardSlash = request.Path.Value.Substring(1);
string queryStringWithLeadingQuestionCharacter = request.QueryString.Value;
string original = $"{pathExcludingInitialForwardSlash}{queryStringWithLeadingQuestionCharacter}";
string replaced = _regex.Replace(original, _replacement);
if (replaced.StartsWith('/')) { // Replacement pattern may include this character
replaced = replaced.Substring(1);
}
if (original != replaced) { // Case comparison?
string[] parts = replaced.Split('?');
request.Path = $"/{parts[0]}";
request.QueryString = new QueryString(parts.Length == 2 ? $"?{parts[1]}" : "");
context.Result = _resultIfRewrite;
}
else {
context.Result = RuleResult.ContinueRules;
}
}
}
我正在尝试在 asp.net 核心 2.2 中做一些 URL 重写,但它似乎不适用于查询字符串部分。我想将 "finditem?txn=3" 之类的任何路径更改为 "find/item?transactionid=3" 之类的路径。作为一个更简单的例子,没有智能替换 transactionID,看这段代码:
private static RewriteOptions GetRewriteOptions() => new RewriteOptions()
.AddRewrite(@"^bananatxn=\d$", "Download", true) // Works with bananatxn=1
.AddRewrite(@"^banana\?txn=\d$", "Download", true); // Does NOT work with banana?txn=1
为什么重写器无法匹配问号字符?我已经在 http://regexstorm.net/tester 中测试了我的模式,虽然模式似乎是正确的,但它不起作用。 asp.net 核心中的重写器可以重写整个 URL,包括查询字符串,还是只重写问号之前的部分?
我已经调查并认为(但不确定)此功能在 asp.net 核心提供的内置规则中不可用。这对我有用。绝对没有经过彻底测试,可能过于重视大小写,而且我对所有 URL 组件和格式都不太熟悉。
public class RewritePathAndQuery : IRule
{
private Regex _regex;
private readonly string _replacement;
private readonly RuleResult _resultIfRewrite;
/// <param name="regex">Pattern for the path and query, excluding the initial forward slash.</param>
public RewritePathAndQuery(string regex, string replacement, bool skipRemainingRules)
{
_regex = new Regex(regex);
_replacement = replacement;
_resultIfRewrite = skipRemainingRules ? RuleResult.SkipRemainingRules : RuleResult.ContinueRules;
}
public void ApplyRule(RewriteContext context)
{
HttpRequest request = context.HttpContext.Request;
string pathExcludingInitialForwardSlash = request.Path.Value.Substring(1);
string queryStringWithLeadingQuestionCharacter = request.QueryString.Value;
string original = $"{pathExcludingInitialForwardSlash}{queryStringWithLeadingQuestionCharacter}";
string replaced = _regex.Replace(original, _replacement);
if (replaced.StartsWith('/')) { // Replacement pattern may include this character
replaced = replaced.Substring(1);
}
if (original != replaced) { // Case comparison?
string[] parts = replaced.Split('?');
request.Path = $"/{parts[0]}";
request.QueryString = new QueryString(parts.Length == 2 ? $"?{parts[1]}" : "");
context.Result = _resultIfRewrite;
}
else {
context.Result = RuleResult.ContinueRules;
}
}
}