从数据库中动态路由的ASP.NET MVC CMS(Dynamic Routes from data

2019-08-31 07:22发布

基本上我有使用ASP.NET MVC一个CMS后台我建立,现在我上移动到前端网站,需要能够根据输入的路线从我的CMS数据库加载页面。

因此,如果用户输入domain.com/students/information,MVC看起来在页面表,看是否存在一个页面,具有符合学生/信息的永久链接,如果是的话它会重定向到页面控制器,然后加载页面来自数据库的数据并将其返回到用于显示的图。

到目前为止,我已经试过有一个包罗万象的路线,但它仅适用两个URL段,所以/学生/资料,但并不/学生/信息/下降。 我不能在网上如何做到这一点发现了什么,所以我虽然我会问在这里,我找到以前和开源ASP.NET MVC CMS和剖析代码。

下面是路由的配置我到目前为止,但我觉得有一种更好的方式来做到这一点。

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

如果有人可以点我在正确的方向上我怎么会去从数据库加载CMS页,最多三个URL段,仍然能够加载核心页面,有一个控制器和动作预定义。

Answer 1:

您可以使用约束来决定是否覆盖默认的路由逻辑。

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

使用它在路由定义一样,

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

现在,如果你在“页面”控制器的“索引”的行动,比如,

public ActionResult Index(string permalink)
{
    //load the content from db with permalink
    //show the content with view
}
  1. 所有的URL会,第一路由被捕获并通过约束来验证。
  2. 如果在数据库中存在永久网址会由Index行动页控制器处理。
  3. 如果没有约束将失败,URL将还原到默认路由(我不知道,如果你有项目中的任何其他控制器,你会如何决定你的404逻辑)。

编辑

为了避免再次在查询页面CMS Index在行动Page控制器,可以使用HttpContext.Items字典一样

在约束

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;

然后在操作,

public ActionResult Index(string permalink)
{
    var page = HttpContext.Items["cmspage"] as CMSPage;
    //show the content with view
}

希望这可以帮助。



文章来源: Dynamic Routes from database for ASP.NET MVC CMS