URLs with slash in parameter?
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 migh开发者_开发百科t be titles like 'AS/400':
http://en.wikipedia.org/wiki/AS/400Incidentially, there is also this one (title 'Slash'):
http://en.wikipedia.org/wiki//And this one:
http://en.wikipedia.org/wiki//dev/nullOverall, 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&AWikipedia 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)
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.
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
@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
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("//");
}
精彩评论