C# 为什么asp.net核心&x27;s的URL重写中间件与以下正则表达式不匹配?

C# 为什么asp.net核心&x27;s的URL重写中间件与以下正则表达式不匹配?,c#,regex,asp.net-core,url-rewriting,C#,Regex,Asp.net Core,Url Rewriting,我正在尝试将asp.net core 3应用程序中的简单url重写为其他url。我使用的重写器如下 app.UseRewriter(new RewriteOptions().AddRewrite(@"^(?i)quote_request.aspx\?id=(.*)", "quote/revise/$1", skipRemainingRules: true)); 但这并不是将(mysite)/quote_request.aspx?id=123匹配并重写到(mysite)/quote/revisi

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

app.UseRewriter(new RewriteOptions().AddRewrite(@"^(?i)quote_request.aspx\?id=(.*)", "quote/revise/$1", skipRemainingRules: true));
但这并不是将(mysite)/quote_request.aspx?id=123匹配并重写到(mysite)/quote/revision/123

我错过什么了吗?不过,正则表达式在这一点上非常匹配

而且


正在正确地重写(mysite)/quote\u request.aspx?id=123到(mysite)/quote/revision?id=123。为了找到答案,我必须查看重写规则的代码。下面是
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\u Request.aspx
请求到
quote\u Request.aspx?id=123
,而缺少的部分位于
context.HttpContext.Request.QueryString
中!所以它只会忽略
之后的url部分,即使传递的正则表达式是正确的,也不会应用规则。因此,为了避免跳过查询,您必须基于现有的
RewriteRule
类编写自定义
IRule
,下面是一个简化的示例:

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

您有权访问任何错误或日志吗?没有,没有错误,我只是从这个重写器中间件开始,所以还没有配置任何日志。第一条规则不匹配,根据我的理解,应该匹配。非常感谢,非常感谢。我怀疑这一点。我想知道在re-writer的默认实现中仅仅使用path和忽略查询字符串背后的动机是什么。此外,我试图将不区分大小写的“quote_request.aspx”与“^(?I)quote_request.aspx$”完全匹配。但它并不匹配。你知道为什么不匹配吗?
var options = new RewriteOptions().Add(new CustomRewriteRule(@"^(?i)quote_request.aspx\?id=(.*)", "quote/revise/$1", true));
app.UseRewriter(options);