我正在寻找一个很好的解决方案,有一个适用于标准ASP.NET MVC控制器/动作URL的URL方案,例如:
/Home/About --> Controller "Home", Action "About"
和虚荣/ slug网址例如:
/fred/post --> Controller "Posts", Action "View", User "fred", Post "post"
重要的是,我希望出站网址生成能够正常工作
Html.ActionLink("View", "Posts", new { User="fred", Post="post" }, null }
给/ fred / post - not / Posts / View / fred / post
看起来,我可以让它为入站或出站路由工作,但不能同时工作。或者我可以得到它的工作,但它是凌乱的,容易破碎。有什么方法,提示和技巧可以让这样的东西干净利落地工作?
答案 0 :(得分:2)
我终于提出了使用路由约束的解决方案,该约束可以检查参数是否与控制器的名称匹配(或不匹配):
public class ControllerConstraint : IRouteConstraint
{
static List<string> ControllerNames = (from t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
where typeof(IController).IsAssignableFrom(t) && t.Name.EndsWith("Controller")
select t.Name.Substring(0, t.Name.Length - 10).ToLower()).ToList();
bool m_bIsController;
public ControllerConstraint(bool IsController)
{
m_bIsController = IsController;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (m_bIsController)
return ControllerNames.Contains(values[parameterName].ToString().ToLower());
else
return !ControllerNames.Contains(values[parameterName].ToString().ToLower());
}
}
像这样使用:
// eg: /myusername
routes.MapRoute(
"MemberUrl",
"{member_urlid}",
new { controller = "Members", action = "View" },
new { action="View", member_urlid = new ControllerConstraint(false) }
);
// eg: /myusername/mypagename
routes.MapRoute(
"ItemUrl",
"{member_urlid}/{item_urlid}",
new { controller = "Items", action = "View" },
new { action="View", member_urlid = new ControllerConstraint(false) }
);
// Normal controller/action routes follow
如果参数与控制器的名称匹配,则约束new ControllerConstraint(false)
表示与此路由规则不匹配。传递true以使约束检查参数是否与控制器名称匹配。