您可以使用约束来决定是否覆盖默认路由逻辑。
public class CmsUrlConstraint : IRouteConstraint{ public bool Match(HttpContextbase httpContext, Route route, string parameterName, RoutevalueDictionary values, RouteDirection routeDirection) { var db = new MvcCMS.Models.MvcCMSContext(); if (values[parameterName] != null) { var permalink = values[parameterName].ToString(); return db.CMSPages.Any(p => p.Permalink == permalink); } return false; }}在路由定义中使用它,例如
routes.MapRoute( name: "CmsRoute", url: "{*permalink}", defaults: new {controller = "Page", action = "Index"}, constraints: new { permalink = new CmsUrlConstraint() });routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });现在,如果您在“页面”控制器中执行“索引”操作,
public ActionResult Index(string permalink){ //load the content from db with permalink //show the content with view}- 所有网址将被第一个路由捕获,并由约束条件进行验证。
- 如果永久链接存在于db中,则URL将由Page控制器中的Index操作处理。
- 如果不是这样,约束将失败并且URL将回退到默认路由(我不知道您在项目中是否还有其他控制器以及如何决定404逻辑)。
编辑
为了避免
Index在
Page控制器的操作中重新查询cms页面,可以使用
HttpContext.Items字典,例如
在约束中
var db = new MvcCMS.Models.MvcCMSContext();if (values[parameterName] != null){ var permalink = values[parameterName].ToString(); var page = db.CMSPages.Where(p => p.Permalink == permalink).FirstOrDefault(); if(page != null) { HttpContext.Items["cmspage"] = page; return true; } return false;}return false;然后在行动中
public ActionResult Index(string permalink){ var page = HttpContext.Items["cmspage"] as CMSPage; //show the content with view}希望这可以帮助。



