首页 > 解决方案 > 为什么 asp.net core 的 URL Rewriting 中间件不匹配下面的正则表达式?

问题描述

我正在尝试将简单的 url 重写为 asp.net core 3 应用程序中的其他 url。我使用重写器如下

app.UseRewriter(new RewriteOptions().AddRewrite(@"^(?i)quote_request.aspx\?id=(.*)", "quote/revise/$1", skipRemainingRules: true));

但这不是匹配和重写 (mysite)/quote_request.aspx?id=123 到 (mysite)/quote/revise/123

我错过了什么吗?不过,正则表达式与https://dotnetfiddle.net/vk0ZVn完美匹配。

还,

app.UseRewriter(new RewriteOptions().AddRewrite(@"^(?i)quote_request.aspx(.*)", "quote/revise$1", skipRemainingRules: true));

正确地将 (mysite)/quote_request.aspx?id=123 重写为 (mysite)/quote/revise?id=123。

标签: c#regexasp.net-coreurl-rewriting

解决方案


我必须查看代码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请求!因此,即使传递的正则表达式是正确的,它也会忽略部分 url,并且不应用规则。因此,为了避免跳过查询,您必须根据现有类编写自定义,这里是简化示例:quote_request.aspx?id=123context.HttpContext.Request.QueryString?IRuleRewriteRule

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);

推荐阅读