c# - 来自 ASP.NET MVC CMS 数据库的动态路由

标签 c# asp.net-mvc-4 routes

基本上我有一个使用 ASP.NET MVC 构建的 CMS 后端,现在我要转到前端站点并且需要能够根据输入的路由从我的 CMS 数据库加载页面。

因此,如果用户输入 example.com/students/information,MVC 将在页面表中查找是否存在具有与 students/information 匹配的永久链接的页面,如果存在,它将重定向到页面 Controller ,然后从数据库中加载页面数据并返回给 View 显示。

到目前为止,我已经尝试过捕获所有路由,但它只适用于两个 URL 段,所以 /students/information,而不是 /students/information/fall。我在网上找不到任何关于如何实现这一点的信息,所以我想先在这里问一下,然后再找到并开源 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 段,并且仍然能够加载核心页面,这些页面有一个预定义的 Controller 和操作。

最佳答案

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

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

现在,如果您在“页面” Controller 中有一个“索引”操作,例如,

public ActionResult Index(string permalink)
{
    //load the content from db with permalink
    //show the content with view
}
  1. 所有 url 都将被第一个路由捕获并由约束进行验证。
  2. 如果数据库中存在永久链接,则 url 将由页面 Controller 中的索引操作处理。
  3. 否则约束将失败并且 url 将回退到默认路由(我不知道项目中是否有任何其他 Controller 以及您将如何决定 404 逻辑)。

编辑

为了避免在 Page Controller 的 Index 操作中重新查询 cms 页面,可以使用 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
}

希望这对您有所帮助。

关于c# - 来自 ASP.NET MVC CMS 数据库的动态路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16026441/

相关文章:

javascript - knockout 可观察到未受到约束

javascript - Angular 2 - 路由 useAsDefault 不起作用

symfony - 奏鸣曲管理员通过显示链接更改编辑链接

c# - Xamarin 从返回值的覆盖调用异步函数

c# - Eric Lippert 的挑战 "comma-quibbling",最佳答案?

c# - WCF 从引用程序集返回某种类型的对象

c# - .NET 正则表达式匹配和替换

asp.net-mvc - 在 Windows 8 中的 IIS 8 上使用 .NET 4.5 的 MVC 4 网站给出 403.14 禁止错误

javascript - 双 ToString 保持 "en-US"格式

angularjs - 从 ngRoute/$routeProvider 迁移到 ui-router/$urlRouterProvider