asp.net-mvc 参数中带斜杠的网址?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6328713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 01:15:12  来源:igfitidea点击:

URLs with slash in parameter?

asp.net-mvcasp.net-mvc-routing

提问by Stefan Steiger

Question:

题:

I am creating a wiki software, basically a clone of wikipedia/mediawiki, but in ASP.NET MVC (the MVC is the point, so don't recommend me ScrewTurn).

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

Now I have a question:

现在我有一个问题:

I use this route mapping, to route a URL like:
http://en.wikipedia.org/wiki/ASP.NET

我使用这个路由映射来路由一个 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
        );

Now it just occured to me, that there might be titles like 'AS/400':
http://en.wikipedia.org/wiki/AS/400

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

Incidentially, there is also this one (title 'Slash'):
http://en.wikipedia.org/wiki//

顺便说一句,还有这个(标题“斜线”):http:
//en.wikipedia.org/wiki//

And this one:
http://en.wikipedia.org/wiki//dev/null

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

Overall, Wikipedia seems to have a list of interesting titles like this: http://en.wikipedia.org/wiki/Wikipedia:Articles_with_slashes_in_title

总的来说,维基百科似乎有一个像这样有趣的标题列表:http: //en.wikipedia.org/wiki/Wikipedia: Articles_with_slashes_in_title

How do I make routes like this route correctly ?

我如何正确地制作这样的路线?

Edit:
Something like:
If the URL starts with /Wiki/, and if it doesn't start with /wiki/Edit/ (but not /Wiki/Edit) then pass all the rest of the URL as Id.

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

Edit:
Hmm, just another problem: How can I route this one:
http://en.wikipedia.org/wiki/C&A

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

Wikipedia can...

维基百科可以...

Edit:
According to wikipedia, due to clashes with wikitext syntax, only the following characters can never be used in page titles (nor are they supported by DISPLAYTITLE):

编辑:
根据维基百科,由于与 wikitext 语法的冲突,只有以下字符永远不能用于页面标题(DISPLAYTITLE 也不支持它们):

# < > [ ] | { }

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

http://en.wikipedia.org/wiki/Wikipedia:Naming_conventions_(technical_restrictions)#Forbidden_​​characters

Edit:
To allow * and &, put

编辑:
为了允许 * 和 &,把

<httpRuntime requestPathInvalidCharacters="" />

into section <system.web> in file web.config

进入文件 web.config 中的 <system.web> 部分

(Found here: http://www.christophercrooker.com/use-any-characters-you-want-in-your-urls-with-aspnet-4-and-iis)

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

回答by Darin Dimitrov

You could use a catchall route to capture everything that follows the wikipart of the url into the idtoken:

您可以使用笼统的路由wiki将 url 部分后面的所有内容捕获到id令牌中:

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

Now if you have the following request: /wiki/AS/400it will map to the following action on the Wikicontroller:

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

public ActionResult DbLookup(string id)
{
    // id will equal AS/400 here
    ...
}

As far as /wiki//is concerned I believe you will get a 400 Bad Request error from the web server before this request ever reaches the ASP.NET pipeline. You may checkout the following blog post.

至于/wiki//来讲我认为这个要求是以往任何时候都达到ASP.NET管道,你会得到从Web服务器400错误请求错误。您可以查看以下博客文章

回答by Usman

in Attribute Routingin mvc i had the same problem having /in string abc/cdein HttpGet

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

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

so you have to place *because after this it will be considered as parameter

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

回答by Adam

@Darin: Well, that much is obvious, the question is: Why ? controller + action + id are given, it's like it's passing all these to routing again... – Quandary Jun 13 '11 at 17:38

@Darin:嗯,这很明显,问题是:为什么?给出了控制器 + 动作 + id,就像它再次将所有这些传递给路由... – Quandary 2011 年 6 月 13 日 17:38

Quandry - maybe you have already figured this out since your question is over a year old, but when you call RedirectToAction, you are actually sending an HTTP 302response to the browser, which causes the browser to make a GET request to the specified action. Hence, the infinite loop you are seeing.

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

See: Controller.RedirectToAction Method

请参阅:Controller.RedirectToAction 方法

回答by bobparker58

Still as an option write in the file Global.asax:

仍然作为选项写入文件 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("//");
    }