参数中带有斜杠的 URL?

发布于 2024-11-15 01:27:06 字数 2182 浏览 3 评论 0原文

问题:

我正在创建一个 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

顺便说一句,还有这个(标题'斜线'):
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/ 开头 (但不是/维基/编辑) 然后将 URL 的其余部分作为 Id 传递。

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

维基百科可以...

编辑:
根据维基百科,由于与维基文本语法冲突,只有以下字符永远不能在页面标题中使用(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

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

Now I have a question:

I use this route mapping, to route a URL like:
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

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

And this one:
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

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.

Edit:
Hmm, just another problem:
How can I route this one:
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):

# < > [ ] | { }

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

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

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

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

发布评论

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

评论(4

趁年轻赶紧闹 2024-11-22 01:27:06

您可以使用包罗万象的路由将网址的 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// 而言,我相信您会得到 400 Bad在该请求到达之前,来自 Web 服务器的请求错误ASP.NET 管道。您可以查看以下博客文章

You could use a catchall route to capture everything that follows the wiki part of the url into the id token:

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

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

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.

终陌 2024-11-22 01:27:06

在mvc中的属性路由中,我在HttpGet中的字符串abc/cde中遇到了同样的问题,

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

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

in Attribute Routing in mvc i had the same problem having / in string abc/cde in 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

半步萧音过轻尘 2024-11-22 01:27:06

@Darin:嗯,这是显而易见的,问题是:为什么?控制器
+ action + id 给定了,就像它再次将所有这些传递给路由... – Quandary 2011-06-13 17:38

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

请参阅:Controller.RedirectToAction 方法

@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

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 302 response to the browser, which causes the browser to make a GET request to the specified action. Hence, the infinite loop you are seeing.

See: Controller.RedirectToAction Method

↘紸啶 2024-11-22 01:27:06

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

Still as an option write in the file 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("//");
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文