Asp.net mvc Asp.net mvc 3.0树结构页面自定义路由
我想将所有CMS页面url映射到单个控制器(PageController)和操作(详细信息) 如何创建自定义路由来映射所有这些URLAsp.net mvc Asp.net mvc 3.0树结构页面自定义路由,asp.net-mvc,seo,asp.net-mvc-routing,url-routing,Asp.net Mvc,Seo,Asp.net Mvc Routing,Url Routing,我想将所有CMS页面url映射到单个控制器(PageController)和操作(详细信息) 如何创建自定义路由来映射所有这些URL /teacher /teacher/kindergarten /teacher/kindergarten/1 /teacher/primary /teacher/primary/english /teacher/primary/language /teacher/primary/language/chinese /teacher/primary/math /tea
/teacher
/teacher/kindergarten
/teacher/kindergarten/1
/teacher/primary
/teacher/primary/english
/teacher/primary/language
/teacher/primary/language/chinese
/teacher/primary/math
/teacher/primary/science
/parent
/parent/kindergarten
/parent/primary1-3
/parent/primary4-6
/leader
/leader/kindergarten
/leader/kindergarten/1
如果数据库中有这些URL,则可以在应用程序启动时映射路由:
var pages = siteDB.Pages.ToList();
string pagePath = "";
foreach (var page in pages)
{
routeVals = new RouteValueDictionary();
constraints = new RouteValueDictionary();
routeVals.Add("controller", "page");
routeVals.Add("action", "details");
constraints.Add("path", "[a-zA-Z0-9\\-]*");
// any child pages? must add these routes before their parent pages.
var childPages = siteDB.Pages.Where(p => p.ParentPageId == page.PageId).ToList();
foreach (var childPage in childPages)
{
pagePath = BuildPath(childPage);
RouteTable.Routes.Add(new Route(pagePath, new MvcRouteHandler())
{
Defaults = routeVals,
Constraints = constraints,
DataTokens =
new RouteValueDictionary {
{ "pageid", childPage.PageId },
{ "path", pagePath }
}
});
// Any further child pages? (Only 3 levels supported)
var childSubPages = siteDB.Pages.Where(p => p.ParentPageId == childPage.PageId).ToList();
foreach (var childSubPage in childSubPages)
{
pagePath = BuildPath(childSubPage);
RouteTable.Routes.Add(new Route(pagePath, new MvcRouteHandler())
{
Defaults = routeVals,
Constraints = constraints,
DataTokens =
new RouteValueDictionary {
{ "pageid", childSubPage.PageId },
{ "path", pagePath }
}
});
}
}
此代码从数据库中获取页面,这些页面通过父id链接
以下是生成每个页面的完整路径的BuildPath函数:
public static string BuildPath(Page page)
{
if (page.ParentPageId == 1)
{
return page.PageKey;
}
else
{
SiteDataEntities siteDB = new SiteDataEntities();
string path = page.PageKey;
Page parent = siteDB.Pages.Find(page.ParentPageId);
while (parent != null)
{
path = parent.PageKey + "/" + path;
parent = siteDB.Pages.Find(parent.ParentPageId);
if (parent.PageKey == "home") break;
}
return path;
}
}
以前提出的解决方案仅适用于少量页面。 因为根据守则: 应用程序生成并注册每个站点页面的路由。结果,我们至少有相同数量的路由作为网页在我们的网站。正如您可能知道的,RouteModule必须逐个路由检查每个路由,以找到第一个正确的路由,并执行正确的处理程序、控制器、操作、视图 解决这个问题还有两种方法:
- 您可以创建一个从RouteBase派生的类,并实现所需的属性和方法:将url拆分为段,确定当前页面使用pageid、path、parents等填充RouteValueDictionary
- 您可以使用自定义URLEwriteModule。将所有请求url从树状结构转换为mvc默认路由的想法: {controller}/{action}/{id}?path=parentlevel1/parent2/parent3/
当您有不同的控制器时,该解决方案也很有用,正确的控制器我们可以通过当前页面确定(按页面数据:类型)谢谢Sam,这就是我要找的。非常感谢=)嗨,Sam,BuildPath函数将做什么?刚刚添加了BuildPath函数和解释。这里介绍了另一种方法: