我正在尝试在路线上设置特定约束。我的URL必须如下所示:http://hostname/id-my-title-can-be-that-long其中id仅由数字组成,标题为带有破折号分隔符的小写字符。 id和标题也用短划线分隔。例如:http://hostname/123-my-title。
这是我的路线定义:
routes.MapRoute(
"Test",
"{id}-{title}",
new { controller = "Article", action = "Index" },
new { id = @"(\d)+", title = @"([a-z]+-?)+" }
);
使用html帮助程序正确生成URL:
<%: Html.ActionLink("My link", "Index", "Article", new { id = Model.IdArticle, title = Model.UrlTitle }, null) %>
当然,Model.IdArticle是一个Int32,而Model.UrlTitle是我的标题的预先形成的字符串,符合我的要求(仅限小写,空格由短划线替换)。
问题是,当我按照链接时,正确的控制器&amp;方法未被调用,它落入下一个错误的路径。
对于记录,我使用的是ASP.NET MVC 2.
有人有想法吗?
提前致谢, 费边
答案 0 :(得分:0)
您可以尝试传递整个路径字符串“{id} - {title}”并在进入您的操作之前手动解析字符串,方法是执行与Phil Haack的slug到id actionfilter属性类似的操作 - link
希望这有帮助。
答案 1 :(得分:0)
路线中的几个字符是“特殊的”,并将分割参数,如 - 和/。可能是路由中的额外-s导致其失败。请尝试"{id}-{*title}"
,因为这会使标题包含随后的所有内容。
<强>更新强>
上面的答案是当你喝足够的咖啡之前进入StackOverflow会发生什么。
我们遇到了同样的问题,处理用户上传的文件的文件名,路由包括' - '作为分隔符,但也可以在后面的参数中的值中使用,它可以生成正确的URL但不会'匹配它。最后,我写了一个SpecialFileRoute类来处理这个问题并注册了这条路线。虽然它有点难看,但是做到了。
请注意,我保留了用于生成URL的旧式MVC路由,我正在玩这个以便正确地执行此操作,但这是稍后回来的事情。
/// <summary>
/// Special route to handle hyphens in the filename, a catchall parameter in the commented route caused exceptions
/// </summary>
public class SpecialFileRoute : RouteBase, IRouteWithArea
{
public string Controller { get; set; }
public string Action { get; set; }
public IRouteHandler RouteHandler = new MvcRouteHandler();
public string Area { get; private set; }
//Doc/{doccode} - {CatNumber}.{version} - {*filename},
public SpecialFileRoute(string area)
{
Area = area;
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
string url = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2);
var urlmatch = Regex.Match(url, @"doc/(\w*) - (\d*).(\d*) - (.*)", RegexOptions.IgnoreCase);
if (urlmatch.Success)
{
var routeData = new RouteData(this, this.RouteHandler);
routeData.Values.Add("doccode", urlmatch.Groups[1].Value);
routeData.Values.Add("CatNumber", urlmatch.Groups[2].Value);
routeData.Values.Add("version", urlmatch.Groups[3].Value);
routeData.Values.Add("filename", urlmatch.Groups[4].Value);
routeData.Values.Add("controller", this.Controller);
routeData.Values.Add("action", this.Action);
return routeData;
}
else
return null;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
if (values.ContainsKey("controller") && (!string.Equals(Controller, values["controller"] as string, StringComparison.InvariantCultureIgnoreCase)))
return null;
if (values.ContainsKey("action") && (!string.Equals(Action, values["action"] as string, StringComparison.InvariantCultureIgnoreCase)))
return null;
if ((!values.ContainsKey("contentUrl")) || (!values.ContainsKey("format")))
return null;
return new VirtualPathData(this, string.Format("{0}.{1}", values["contentUrl"], values["format"]));
}
}
路线添加如下:
context.Routes.Add(new SpecialFileRoute(AreaName) { Controller = "Doc", Action = "Download" });
如上所述,这有点难看,当我有时间时,我想做很多工作来改进它,但它解决了将URL拆分为所需参数的问题。它与url模式,Regex和Values硬编码的这一条路线的特定要求密切相关,虽然它应该给你一个开始。