RedirectToRoute 对“/”进行双重编码。在作为routeValues 中的URL 的参数中

发布于 2024-12-02 22:16:48 字数 1004 浏览 1 评论 0原文

我有一个编码问题,我似乎无法处理路线上的参数。基本上,它要么从不进行URL编码,要么双重进行URL编码。我只想要它单编码!

这是我注册的路线:

routes.MapRoute("Scan", "Scan/{*url}", new { controller = "Scan", action = "Index" });

现在我有一个重定向到该路线的控制器操作。为了简单起见,假设它看起来像这样:

var url = "troyhunt.com/search";
return RedirectToRoute("Scan", new { url });

生成的 URL 是“Scan/troyhunt.com/search” - 请注意,.com 后面的正斜杠尚未被转义。

现在让我们再试一次,但应用 URL 编码:

var url = HttpUtility.UrlEncode("troyhunt.com/search");
return RedirectToRoute("Scan", new { url });

这次生成的 URL 是“Scan/troyhunt.com%252fsearch” - 请注意,正斜杠已被双重编码。如果我在重定向之前设置断点,我可以看到 UrlEncode 方法成功地将正斜杠编码为 %2f。

看来重定向正在编码“%”符号,而不是“/”。如果我使用通常使用 URL 编码 (?,=) 转义的其他字符进行测试,则编码可以直接从 RedirectToRoute 方法正常工作。将斜线视为分隔路线段从而不转义是否会出现问题?我在这里还缺少其他东西吗?

更新:更多信息、评论和解决方法在 路由还是不路由,这是一个问题

I have an encoding problem I can't seem to get to grips with regarding a parameter on a route. Basically, it either never URL encodes or it double URL encodes. I just want it single-encoded!

Here's the route I have registered:

routes.MapRoute("Scan", "Scan/{*url}", new { controller = "Scan", action = "Index" });

Now I have a controller action that redirects to that route. For simplicity's sake, let's say it looks like this:

var url = "troyhunt.com/search";
return RedirectToRoute("Scan", new { url });

The resulting URL is "Scan/troyhunt.com/search" - note that the forward slash after .com has not been escaped.

Now let's try that again but apply URL encoding:

var url = HttpUtility.UrlEncode("troyhunt.com/search");
return RedirectToRoute("Scan", new { url });

This time the resulting URL is "Scan/troyhunt.com%252fsearch" - note that the forward slash has been double-encoded. If I set a breakpoint before the redirect I can see the UrlEncode method successfully encoding the forward slash into a %2f.

It appears that the redirect is encoding the "%" symbol but not the "/". If I test with other characters typically escaped with URL encoding (?,=), the encoding is working just fine directly from the RedirectToRoute method. Could this be an issue with treating the slash as separating route segments therefore not escaping? Am I missing something else here?

Update: more info, commentary and workaround is discussed in To route or not to route, that is the question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

坏尐絯 2024-12-09 22:16:48

查看 System.Web.Routing 看起来发生这种情况是因为路由值不是使用 HttpUtility.UrlEncode(value) 进行 URL 编码,但实际上是使用 进行了“转义” Uri.EscapeUriString(值)

有问题的代码位于 System.Web.Routing.ParsedRoute 中:

// Dev10 601636 Work around Uri.EscapeUriString not encoding #,&
    private static string UrlEncode(string str) {
        string escape = Uri.EscapeUriString(str); 
        return Regex.Replace(escape, "([#;?:@&=+$,])", new MatchEvaluator(EscapeReservedCharacters));
    }

可能是设计决定(必须向 Microsoft 人员询问这一点),因为事实上正斜杠是路由中相当重要的一部分。如果是的话,我觉得有点奇怪,因为 文档>Uri.EscapeUriString() 指出它的主要用法为:

使用 EscapeUriString 方法准备一个未转义的 URI 字符串作为 Uri 构造函数的参数。

按照生成路由 URL 的代码,它似乎根本没有使用 Uri 类 - URL 是在字符串中构造并返回的。

如果您将其作为查询字符串参数传递,而不是作为指定路由的一部分,那么它将被正确的 URL 编码(但当然会更改 URL 的结构)。

Looking into System.Web.Routing it looks like this is happening due to the fact that route values are not URL encoded using HttpUtility.UrlEncode(value) but in fact, are "escaped" using Uri.EscapeUriString(value).

The offending code is in System.Web.Routing.ParsedRoute:

// Dev10 601636 Work around Uri.EscapeUriString not encoding #,&
    private static string UrlEncode(string str) {
        string escape = Uri.EscapeUriString(str); 
        return Regex.Replace(escape, "([#;?:@&=+$,])", new MatchEvaluator(EscapeReservedCharacters));
    }

This could be a by design decision (would have to ask the Microsoft folks about that), due to the fact that forward slashes are a fairly integral part of routes. If it is I find it a little strange as the documentation for Uri.EscapeUriString() states that it's main usage as:

Use the EscapeUriString method to prepare an unescaped URI string to be a parameter to the Uri constructor.

Following through the code that generates the route URL, it doesn't seem to use the Uri class at all - the URL is constructed and returned in a string.

If you passed this as a query string parameter, rather than as part of a specified route, it would be properly URL encoded (but would of course change the structure of your URL).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文