从数据库动态路由ASP.NET MVC的CMS [英] Dynamic Routes from database for ASP.NET MVC CMS

查看:137
本文介绍了从数据库动态路由ASP.NET MVC的CMS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

因此​​,如果用户输入domain.com/students/information,MVC看起来在页面表,以查看是否存在一个页面具有匹配学生/信息的固定链接,如果是的话,将重定向到页面控制器,然后从数据库加载该网页数据,并将其返回到用于显示的图。

到目前为止,我已经试过有一个包罗万象的路线,但它仅适用两个URL段,所以/生/信息,但不/生/信息/下降。我不能就如何完成这个网上找到任何东西,所以我虽然我会问这里,我发现之前的开源ASP.NET MVC CMS和解剖code。

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

 公共静态无效的RegisterRoutes(RouteCollection路线)
    {
        routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);        //默认路由处理核心页面
        routes.MapRoute(NULL,{控制器} / {行动} / {ID}
                        新{行动=索引,ID = UrlParameter.Optional},
                        新{控制器=索引}
        );        // CMS途径来处理路由到的PageController检查数据库的路径。
        变种DB =新Mv​​cCMS.Models.MvcCMSContext();
        // VAR页= db.CMSPages.Where(P => p.Permalink ==)
        routes.MapRoute(
            空值,
            {*},
            新{控制器=页面,行动=索引}
        );
    }

如果任何人都可以点我在正确的方向上我怎么会去从数据库加载CMS页,最多三个URL部分,仍然可以加载核心页面,有一个控制器和动作predefined。


解决方案

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

 公共类CmsUrlConstraint:IRouteConstraint
{
    公共BOOL匹配(HttpContextBase HttpContext的,路由路径,字符串参数名称,RouteValueDictionary价值,RouteDirection routeDirection)
    {
        变种DB =新Mv​​cCMS.Models.MvcCMSContext();
        如果(值[参数名称]!= NULL)
        {
            VAR永久=值[参数名称]的ToString();
            返回db.CMSPages.Any(P => p.Permalink ==永久);
        }
        返回false;
    }
}

在路由定义中使用它像,

  routes.MapRoute(
    名称:CmsRoute
    网址:{*}固定链接
    默认:新{控制器=页面,行动=索引},
    限制:新{永久=新CmsUrlConstraint()}
);routes.MapRoute(
    名称:默认,
    网址:{控制器} / {行动} / {ID}
    默认:新{控制器=家,行动=索引,ID = UrlParameter.Optional}
);

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

 公众的ActionResult指数(字符串永久)
{
    //从数据库与永久加载内容
    //显示可观看的内容
}


  1. 所有的URL将被第一条路被捕获并通过约束来验证。

  2. 如果将永久存在于数据库的URL会被索引行动页面控制器进行处理。

  3. 如果没有约束将失败,URL将退回到默认路由(我不知道,如果你有项目中的任何其他控制器,你会如何决定你的404逻辑)。

修改

要避免再次查询在首页行动CMS页面控制器,可以使用 HttpContext.Items 词典,像

在约束

 变种DB =新Mv​​cCMS.Models.MvcCMSContext();
如果(值[参数名称]!= NULL)
{
    VAR永久=值[参数名称]的ToString();
    VAR页= db.CMSPages.Where(P => p.Permalink ==永久).FirstOrDefault();
    如果(页面!= NULL)
    {
        HttpContext.Items [cmspage] =页;
        返回true;
    }
    返回false;
}
返回false;

然后在操作,

 公众的ActionResult指数(字符串永久)
{
    VAR页= HttpContext.Items [cmspage]作为CMSPage;
    //显示可观看的内容
}

希望这有助于。

Basically I have a CMS backend I built using ASP.NET MVC and now I'm moving on to the frontend site and need to be able to load pages from my cms database, based on the route entered.

So if the user enters domain.com/students/information, MVC would look in the pages table to see if a page exists that has a permalink that matches students/information, if so it would redirect to the page controller and then load the page data from the database and return it to the view for display.

So far I have tried to have a catch all route, but it only works for two URL segments, so /students/information, but not /students/information/fall. I can't find anything online on how to accomplish this, so I though I would ask here, before I find and open source ASP.NET MVC cms and dissect the code.

Here is the route configuration I have so far, but I feel there is a better way to do this.

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

If anybody can point me in the right direction on how I would go about loading CMS pages from the database, with up to three URL segments, and still be able to load core pages, that have a controller and action predefined.

解决方案

You can use a constraint to decide whether to override the default routing logic.

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

use it in route definition like,

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

Now if you have an 'Index' action in 'Page' Controller like,

public ActionResult Index(string permalink)
{
    //load the content from db with permalink
    //show the content with view
}

  1. all urls will be caught by the first route and be verified by the constraint.
  2. if the permalink exists in db the url will be handled by Index action in Page controller.
  3. if not the constraint will fail and the url will fallback to default route(i dont know if you have any other controllers in the project and how you will decide your 404 logic).

EDIT

To avoid re querying the cms page in the Index action in Page controller, one can use the HttpContext.Items dictionary, like

in the constraint

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;

then in the action,

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

hope this helps.

这篇关于从数据库动态路由ASP.NET MVC的CMS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆