小编典典
您可以使用约束来决定是否覆盖默认路由逻辑。
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
}
希望这可以帮助。
2020-05-19