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.
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
}
- wszystkie adresy URL zostaną przechwycone przez pierwszą trasę i zweryfikowane przez ograniczenie.
- jeśli permalink istnieje w db, adres url będzie obsługiwany przez akcję Index w kontrolerze strony.
- 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.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