2013-04-15 13 views
59

Về cơ bản tôi có một chương trình phụ trợ CMS được xây dựng bằng ASP.NET MVC và bây giờ tôi đang chuyển sang trang web giao diện và cần tải các trang từ cơ sở dữ liệu cms của mình, dựa trên tuyến đường đã nhập. Vì vậy, nếu người dùng nhập domain.com/students/information, MVC sẽ xem trong bảng trang để xem liệu trang có tồn tại có liên kết cố định phù hợp với sinh viên/thông tin hay không, nếu như vậy nó sẽ chuyển hướng đến bộ điều khiển trang và sau đó tải dữ liệu trang từ cơ sở dữ liệu và đưa nó trở lại màn hình để hiển thị.Các tuyến động từ cơ sở dữ liệu cho ASP.NET MVC CMS

Cho đến nay tôi đã cố gắng nắm bắt tất cả tuyến đường, nhưng nó chỉ hoạt động cho hai đoạn URL, vì vậy/sinh viên/thông tin, nhưng không phải/sinh viên/thông tin/mùa thu. Tôi không thể tìm thấy bất cứ điều gì trực tuyến về cách thực hiện điều này, vì vậy tôi mặc dù tôi sẽ yêu cầu ở đây, trước khi tôi tìm và mã nguồn mở ASP.NET MVC cms và mổ xẻ mã.

Đây là cấu hình tuyến đường tôi có cho đến nay, nhưng tôi cảm thấy có cách tốt hơn để thực hiện việc này.

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

Nếu ai có thể chỉ cho tôi đi đúng hướng trên thế nào tôi sẽ đi về tải trang CMS từ cơ sở dữ liệu, với tối đa ba phân đoạn URL, và vẫn có thể tải các trang lõi, có một bộ điều khiển và hành động được xác định trước.

Trả lời

106

Bạn có thể sử dụng ràng buộc để quyết định có ghi đè lên logic định tuyến mặc định hay không.

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

sử dụng nó trong định nghĩa con đường như thế nào,

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

Bây giờ nếu bạn có một hành động 'Index' trong 'Trang' điều khiển như thế nào,

public ActionResult Index(string permalink) 
{ 
    //load the content from db with permalink 
    //show the content with view 
} 
  1. tất cả các url sẽ bị bắt bởi tuyến đường đầu tiên và được xác minh bởi ràng buộc.
  2. nếu liên kết cố định tồn tại trong db, url sẽ được xử lý bằng thao tác Chỉ mục trong Trình điều khiển trang.
  3. nếu không phải ràng buộc sẽ thất bại và url sẽ dự phòng tuyến mặc định (tôi không biết nếu bạn có bất kỳ bộ điều khiển nào khác trong dự án và cách bạn sẽ quyết định logic 404 của mình).

EDIT

Để tránh tái truy vấn trang cms trong hành động Index trong Page điều khiển, người ta có thể sử dụng từ điển HttpContext.Items, như

trong chế

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; 

sau đó trong hành động,

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

hy vọng điều này sẽ hữu ích.

+0

Cảm ơn bạn rất nhiều, tôi sẽ thử điều này và đánh dấu là câu trả lời nếu nó hoạt động. :) –

+3

Tuyệt vời nó đã làm việc tuyệt vời, chỉ cần thêm một kiểm tra nếu (giá trị [parameterName]! = Null), nhưng nếu không hoàn hảo! Cảm ơn bạn :) –

+1

bạn được chào đón. vui mừng nó đã làm việc ra ngoài. :) – shakib