Asp.net MVC 3.0 древовидная структура страницы пользовательской маршрутизации - PullRequest
1 голос
/ 30 июня 2011

Я хочу сопоставить все URL-адреса страниц CMS с одним контроллером (PageController) и действием (Подробности).

Как создать собственную маршрутизацию для сопоставления всех этих URL-адресов?

/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

Ответы [ 2 ]

1 голос
/ 23 мая 2012

Предыдущее предлагаемое решение работает только для небольшого количества страниц. Потому что по коду:

Приложение генерирует и регистрирует маршрут для каждой страницы сайта. В результате у нас есть как минимум то же количество маршрутов, что и страниц нашего сайта. Как вы, наверное, знаете, RouteModule должен проверять маршрут по маршруту, чтобы каждый из них нашел первый правильный и выполнить правильный обработчик, контроллер, действие, представление ...

Есть два способа решить эту проблему:

  • Вы можете создать класс, производный от RouteBase, и реализовать нужные вам свойства и методы: разделить URL на сегменты, определить заполнение текущей страницы RouteValueDictionary с помощью pageid, path, parent и т. Д.

  • Вы можете настроить UrlRewriteModule с пользовательским провайдером перезаписи . Идея преобразовать URL всех запросов из базовой структуры дерева в маршрут по умолчанию для mvc:

    {контроллер} / {действие} / {ID}? Путь = parentlevel1 / parent2 / parent3 /....

90% -ный код для обоих вариантов может быть подготовлен. это решение также может быть полезно, когда у вас есть разные контроллеры, исправьте тот, который мы могли бы определить по текущей странице (по данным страницы: тип)

1 голос
/ 30 июня 2011

Если у вас есть эти 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 }
              }
            });
        }
    }

Этот код берет страницы из базы данных, где они связаны родительским идентификатором.

Вот функция 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;
  }
}
...