问题:
我正在创建一个wiki软件,基本上是维基百科/ 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 /编辑)
然后将所有其余的URL传递为Id。
编辑:
嗯,只是另一个问题:
我如何路由这一个:
http://en.wikipedia.org/wiki/C&A
维基百科可以......
修改
根据维基百科,由于与wikitext语法的冲突,只有以下字符永远不会在页面标题中使用(DISPLAYTITLE也不支持):
# < > [ ] | { }
修改
允许*和&amp ;,放
<httpRuntime requestPathInvalidCharacters="" />
进入部分&lt; system.web&gt;在文件web.config
中(见http://www.christophercrooker.com/use-any-characters-you-want-in-your-urls-with-aspnet-4-and-iis)
答案 0 :(得分:88)
您可以使用catchall路线将{ur} 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。
答案 1 :(得分:10)
Attribute Routing
mvc中的我在/
abc/cde
中遇到HttpGet
同样的问题
[Route("verifytoken/{*token}")]
[AllowAnonymous]
[HttpGet]
public ActionResult VerifyToken(string token)
{
//logic here
}
因此您必须放置*
,因为在此之后它将被视为参数
答案 2 :(得分:5)
@Darin:嗯,这很明显,问题是:为什么?调节器 给出了+ action + id,就好像它将所有这些都传递给了路由... - Quandary 2011年6月13日17:38
Quandry - 也许你已经解决了这个问题,因为你的问题已经超过一年了,但是当你调用RedirectToAction时,你实际上是在向浏览器发送 HTTP 302 响应,这会导致浏览器向指定的操作发出GET请求。因此,你看到的是无限循环。
答案 3 :(得分:-3)
仍作为选项写入文件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("//");
}