参数中带有斜杠的 URL?

Posted

技术标签:

【中文标题】参数中带有斜杠的 URL?【英文标题】:URLs with slash in parameter? 【发布时间】:2011-09-13 19:07:24 【问题描述】:

问题:

我正在创建一个 wiki 软件,基本上是 wikipedia/mediawiki 的克隆,但在 ASP.NET MVC 中(MVC 是重点,所以不推荐我使用ScrewTurn)。

现在我有一个问题:

我使用此路由映射来路由如下 URL:http://en.wikipedia.org/wiki/ASP.NET

        routes.MapRoute(
            "Wiki", // Routenname
            //"controller/action/id", // URL mit Parametern
            "wiki/id", // URL mit Parametern
            new  controller = "Wiki", action = "dbLookup", id = UrlParameter.Optional  // Parameterstandardwerte
        );

现在我突然想到,可能会有像“AS/400”这样的标题:http://en.wikipedia.org/wiki/AS/400

顺便说一句,还有这个(标题'Slash'):http://en.wikipedia.org/wiki//

还有这个:http://en.wikipedia.org/wiki//dev/null

总的来说,***似乎有一个有趣的标题列表,如下所示: http://en.wikipedia.org/wiki/Wikipedia:Articles_with_slashes_in_title

如何正确地制作类似这条路线的路线?

编辑: 类似的东西: 如果 URL 以 /Wiki/ 开头,并且不以 /wiki/Edit/ 开头 (但不是 /Wiki/Edit) 然后将 URL 的所有其余部分作为 Id 传递。

编辑: 嗯,又是一个问题: 我该如何路由这个:http://en.wikipedia.org/wiki/C&A

***可以...

编辑: 根据 wikipedia,由于与 wikitext 语法冲突,只有以下字符不能用于页面标题(DISPLAYTITLE 也不支持):

# < > [ ] |  

http://en.wikipedia.org/wiki/Wikipedia:Naming_conventions_(technical_restrictions)#Forbidden_characters

编辑: 要允许 * 和 &,放

<httpRuntime requestPathInvalidCharacters="" />

进入文件 web.config 中的 部分

(在这里找到:http://www.christophercrooker.com/use-any-characters-you-want-in-your-urls-with-aspnet-4-and-iis)

【问题讨论】:

您能否将您的路由参数字符更改为“更常见”的字符,例如问号或逗号...标题中的某些内容无效? ASP.NET MVC 路由不是您唯一的问题。尝试“LPT”、“SQL*plus”、“US$”、“C#”等主题。其中很多会被 IIS 捕获。你最好考虑逃离其中的一些。 【参考方案1】:

您可以使用包罗万象的路由将 URL 的 wiki 部分之后的所有内容捕获到 id 令牌中:

routes.MapRoute(
    "Wiki",
    "wiki/*id",
     new  controller = "Wiki", action = "DbLookup", id = UrlParameter.Optional 
);

现在,如果您有以下请求:/wiki/AS/400,它将映射到 Wiki 控制器上的以下操作:

public ActionResult DbLookup(string id)

    // id will equal AS/400 here
    ...

/wiki// 而言,我相信在此请求到达 ASP.NET 管道之前,您会从 Web 服务器收到 400 Bad Request 错误。您可以查看following blog post。

【讨论】:

很好,这行得通,但是当我想从这条规则中排除 /wiki/Edit/ArticleTitle 时呢? (但不应例外 /wiki/Edit) @Quandary,我认为你不能用一个包罗万象的规则来豁免。您可以尝试定义另一条路线之前我展示的路线看起来像这样wiki/Edit/*id @Darin:好的,效果很好。在 Edit 中,这需要捕获 id isnullorempty 并重定向到 id 为 Edit 的 action action dbLookup。 @Darin:如果在编辑操作中,我执行 if (string.IsNullOrEmpty(id)) return RedirectToAction("dbLookup", "Wiki", new id = "Edit" );然后我进入一个无限循环......为什么? @Quandary,我猜RedirectToAction("dbLookup", "Wiki", new id = "Edit" ) 再次解析为编辑操作。【参考方案2】:

@Darin:嗯,这很明显,问题是:为什么?控制器 + action + id 被给出,就好像它再次将所有这些传递给路由...... – Quandary 2011-06-13 17:38:37

Quandry - 也许你已经知道这一点,因为你的问题已经超过一年了,但是当你调用 RedirectToAction 时,你实际上是在向浏览器发送 HTTP 302 响应,这会导致浏览器向指定的操作发出 GET 请求。因此,您看到的是无限循环。

见:Controller.RedirectToAction Method

【讨论】:

Server.Transfer 解决了这个问题:***.com/questions/799511/…【参考方案3】:

在 mvc 中的 Attribute Routing 中,我遇到了同样的问题,在 HttpGet 中的字符串 abc/cde 中存在 /

        [Route("verifytoken/*token")]
        [AllowAnonymous]
        [HttpGet]
        public ActionResult VerifyToken(string token)
        
          //logic here
        

所以你必须放置*,因为在此之后它将被视为参数

【讨论】:

太棒了。这是最好和最简单的解决方案:) 这似乎适用于一个斜线,但不是连续两个。有什么想法吗? @Usman 如果你有另一条路线是 [Route("verifytoken/token/something")] 怎么办?如果有正斜杠,通配符不会与这条路线发生冲突吗?对于这个用例,还有其他方法可以做到这一点吗? 你是英雄!我试图创建一个带有斜线的自定义 url,但没有任何运气,无论我尝试什么,我都得到 /Admin/Customers/Edit?id=1 而不是所需的输出 /Admin/Customers/Edit/1。那个星号成功了!再次感谢 很好的答案。它也适用于 HttpMethodAttribute 。 (.net core 3.1) [HttpGet("verifytoken/*token")] 它也适用于多个斜线。例如:localhost:44352/api/verifytoken/1234/12/23/rebase.pdf token = "1234/12/23/rebase.pdf"【参考方案4】:

仍然可以选择写入文件 Global.asax:

 var uri = Context.Request.Url.ToString();
        if (UriHasRedundantSlashes(uri))
        
            var correctUri = RemoveRedundantSlashes(uri);
            Response.RedirectPermanent(correctUri);
        
    

    private string RemoveRedundantSlashes(string uri)
    
        const string http = "http://";
        const string https = "https://";
        string prefix = string.Empty;

        if (uri.Contains(http))
        
            uri = uri.Replace(http, string.Empty);
            prefix = http;
        
        else if (uri.Contains(https))
        
            uri = uri.Replace(https, string.Empty);
            prefix = https;
        

        while (uri.Contains("//"))
        
            uri = uri.Replace("//", "/");
        

        if (!string.IsNullOrEmpty(prefix))
        
            return prefix + uri;
        
        return uri;
    

    private bool UriHasRedundantSlashes(string uri)
    
        const string http = "http://";
        const string https = "https://";

        if (uri.Contains(http))
        
            uri = uri.Replace(http, string.Empty);
        
        else if (uri.Contains(https))
        
            uri = uri.Replace(https, string.Empty);
        
        return uri.Contains("//");
    

【讨论】:

以上是关于参数中带有斜杠的 URL?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5中带有可选参数的url中的两个斜杠

springboot中URL带有斜杠的转义字符百分之2F导致的400错误

解析没有路径但在查询中带有斜杠的 URL

url传的参数带有 / ,无法传递参数

Laravel 中带有 URL 参数的路由

按钮中的“NoReverseMatch”指的是在 url 中带有参数的页面