Dynamiczne trasy z bazy danych dla ASP.NET MVC CMS

Zasadniczo mam backend CMS, który zbudowałem za pomocą ASP.NET MVC i teraz przechodzę do strony frontend i muszę być w stanie załadować strony z mojej bazy cms, na podstawie wprowadzonej trasy.

Więc jeśli użytkownik wprowadzi domain.com/students/information jeśli tak, to przekieruje do kontrolera strony, a następnie załaduje dane strony z bazy danych i zwróci je do widoku dla wyświetlacz.

Do tej pory próbowałem złapać całą trasę, ale działa tylko dla dwóch segmentów URL, więc /students / information, ale nie/students/information / fall. Nie mogę znaleźć w Internecie nic na temat tego, jak to osiągnąć, więc pomyślałem, że zapytam tutaj, zanim znajdę i open source ASP.NET MVC cms i zapoznaj się z kodem.

Oto konfiguracja trasy, którą mam do tej pory, ale czuję, że jest lepszy sposób, aby to zrobić.

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

        // Default route to handle core pages
        routes.MapRoute(null,"{controller}/{action}/{id}",
                        new { action = "Index", id = UrlParameter.Optional },                  
                        new { controller = "Index" }
        );

        // CMS route to handle routing to the PageController to check the database for the route.


        var db = new MvcCMS.Models.MvcCMSContext();
        //var page = db.CMSPages.Where(p => p.Permalink == )
        routes.MapRoute(
            null,
            "{*.}",
            new { controller = "Page", action = "Index" }
        );          
    }

Jeśli ktoś może wskazać mi właściwy kierunek w jaki Chciałbym przejść o ładowanie stron CMS z bazy danych, z maksymalnie trzech segmentów URL, i nadal być w stanie załadować strony core, które mają kontroler i działania predefiniowane.

Author: Von Lion, 2013-04-16

1 answers

Możesz użyć ograniczenia, aby zdecydować, czy nadpisać domyślną logikę routingu.

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;
    }
}

Użyj go w definicji trasy jak,

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 }
);

Teraz, jeśli masz akcję 'Index' w kontrolerze' Page ' jak,

public ActionResult Index(string permalink)
{
    //load the content from db with permalink
    //show the content with view
}
  1. wszystkie adresy URL zostaną przechwycone przez pierwszą trasę i zweryfikowane przez ograniczenie.
  2. jeśli permalink istnieje w db, adres url będzie obsługiwany przez akcję Index w kontrolerze strony.
  3. jeśli nie ograniczenie nie powiedzie się i adres URL powróci do domyślna trasa (Nie wiem, czy masz jakieś inne kontrolery w projekcie i jak zdecydujesz o swojej logice 404).

EDIT

Aby uniknąć ponownego odpytywania Strony cms w akcji Index w kontrolerze Page, można użyć słownika HttpContext.Items, Jak

W ograniczeniu

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;

Następnie w akcji,

public ActionResult Index(string permalink)
{
    var page = HttpContext.Items["cmspage"] as CMSPage;
    //show the content with view
}
Mam nadzieję, że to pomoże.
 111
Author: shakib,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-05 16:15:17