ASP.NET MVC :Маршрутизация пользовательских слагов без снижения производительности

Я хотел бы создать пользовательские слаги для страниц в моей CMS, чтобы пользователи могли создавать свои собственные URL-адреса SEO -(, такие как Wordpress ).

Раньше я делал это в средах Ruby on Rails и PHP, «злоупотребляя» маршрутом 404. Этот маршрут был вызван, когда запрошенный контроллер не мог быть найден, что позволило мне направить пользователя к моему контроллеру динамических страниц для разбора слага (, откуда я перенаправил их на настоящий 404, если ни одна страница не была найдено ). Таким образом, база данных запрашивалась только для проверки запрошенного слага.

Однако в MVC маршрут catch -all вызывается только тогда, когда маршрут не соответствует маршруту по умолчанию /{controller}/{action}/{id}.

Чтобы по-прежнему иметь возможность анализировать пользовательские слаги, я изменил файл RouteConfig.cs:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        RegisterCustomRoutes(routes);

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { Controller = "Pages", Action = "Index", id = UrlParameter.Optional }
        );
    }

    public static void RegisterCustomRoutes(RouteCollection routes)
    {
        CMSContext db = new CMSContext();
        List<Page> pages = db.Pages.ToList();
        foreach (Page p in pages)
        {
            routes.MapRoute(
                name: p.Title,
                url: p.Slug,
                defaults: new { Controller = "Pages", Action = "Show", id = p.ID }
            );
        }
        db.Dispose();
    }
}

Это решает мою проблему, но требует, чтобы таблица Pagesполностью запрашивалась для каждого запроса. Поскольку перегруженный метод show(public ViewResult Show(Page p))не сработало, мне также нужно получить страницу во второй раз, потому что я могу передать только идентификатор страницы.

  1. Есть ли лучший способ решить мою проблему?
  2. Можно ли передать объект Page моему методу Show вместо идентификатора страницы?
6
задан christiaanderidder 15 July 2012 в 19:05
поделиться