无法重写包含查询字符串成分的网址

时间:2019-01-10 02:26:26

标签: asp.net-core asp.net-core-2.0

我正在尝试在asp.net core 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,包括查询字符串,还是仅重写问号之前的部分?

1 个答案:

答案 0 :(得分:0)

我已经调查并认为(但不确定)此功能在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;
        }
    }
}