2009-10-28 40 views
12

Tôi nhận thấy rằng trong bản xem trước MVC 2 2, AreaRegistration đang tải tuyến đường cho từng khu vực theo thứ tự tùy ý. Có cách nào tốt để lấy cái này trước cái kia không?Khu vực MVC 2Định tuyến tuyến đường Đặt hàng

Ví dụ: tôi có hai khu vực - "Trang web" và "Quản trị". Cả hai đều có bộ điều khiển "Blog".

Tôi muốn sau:

/admin/ --> go to Admin's Blog controller 
/  --> go to Site's Blog controller. 

Vấn đề là nó đang tải tuyến đường của trang web đầu tiên, vì vậy nó được phù hợp với {controller}/{action}/{id} thay vì admin/{controller}/{action}/{id} khi tôi đi đến url "/ admin /". Sau đó tôi nhận được một 404, bởi vì không có bộ điều khiển quản trị trong khu vực "Trang web".

Cả hai khu vực đều mặc định là bộ điều khiển "Blog". Tôi nhận ra rằng tôi có thể chỉ cần đặt site/{controller}/... làm url, nhưng tôi muốn có nó ở gốc nếu có thể. Tôi cũng đã cố gắng giữ đường mặc định trong chức năng RegisterRoutes toàn cầu, tuy nhiên, nó không được gửi đến khu vực "Sites".

Cảm ơn trước!

Trả lời

7

Hiện tại, bạn không thể đặt hàng các khu vực. Tuy nhiên, tôi nghĩ rằng nó có ý nghĩa để cố gắng và làm cho từng khu vực độc lập với các khu vực khác càng tốt nên trật tự không quan trọng.

Ví dụ: thay vì có tuyến đường mặc định {controller}/{action}/{id}, có thể thay thế bằng các tuyến đường cụ thể cho từng bộ điều khiển. Hoặc thêm một ràng buộc vào tuyến đường mặc định đó.

Chúng tôi đang cân nhắc các tùy chọn để cho phép đặt hàng, nhưng chúng tôi không muốn quá phức tạp tính năng này.

+0

Xin chào Phil, cảm ơn lời giải thích. Tôi đã kết thúc di chuyển "trang web" của tôi ra khỏi Khu vực và bây giờ nó là phần "mặc định/không khu vực" (với Chế độ xem và Bộ điều khiển trong thư mục gốc). Sau đó tôi thiết lập paramater namespace của mình cho các controller mặc định để tránh lỗi "ambiguous controller". Ngoài ra, tôi có thể có thể đặt ràng buộc cho một cái gì đó như^((?! admin). *) Để bỏ qua quản trị viên trong các tuyến đường khu vực trang web. Tôi đồng ý, việc thêm độ phức tạp hơn không phải là điều tuyệt vời, mặc dù có vẻ như tuyến đường mvc 1 (không khu vực) có thể có khả năng phụ thuộc nhiều vào trật tự. Cảm ơn! – Jason

+0

Quá trình định tuyến thường phụ thuộc vào thứ tự quy tắc, do đó, tính năng 'đặt hàng' có thể quan trọng. – twk

+0

Vui lòng xem câu trả lời của tôi cho hai kỹ thuật cho phép bạn đặt hàng đăng ký khu vực (và do đó các tuyến đường của họ) theo bất kỳ thứ tự nào. – Eilon

30

Ngoài những gì Haacked cho biết, rất có thể đặt hàng đăng ký khu vực (và do đó các tuyến đường của họ). Tất cả những gì bạn phải làm là đăng ký từng khu vực theo cách thủ công, theo bất cứ thứ tự nào bạn muốn. Nó không phải là kiểu dáng đẹp như gọi RegisterAllAreas() nhưng nó chắc chắn có thể làm được.

protected void Application_Start() { 
    var area1reg = new Area1AreaRegistration(); 
    var area1context = new AreaRegistrationContext(area1reg.AreaName, RouteTable.Routes); 
    area1reg.RegisterArea(area1context); 

    var area2reg = new Area2AreaRegistration(); 
    var area2context = new AreaRegistrationContext(area2reg.AreaName, RouteTable.Routes); 
    area2reg.RegisterArea(area2context); 

    var area3reg = new Area3AreaRegistration(); 
    var area3context = new AreaRegistrationContext(area3reg.AreaName, RouteTable.Routes); 
    area3reg.RegisterArea(area3context); 
} 

Một tùy chọn khác là lấy mã cho RegisterAllAreas(), sao chép mã vào ứng dụng của riêng bạn và xây dựng cơ chế của riêng bạn để xác định đơn đặt hàng. Đó là khá một chút mã để sao chép nếu bạn muốn tất cả các logic bộ nhớ đệm ưa thích mà phương pháp dựng sẵn, nhưng ứng dụng của bạn thậm chí có thể không cần đến nó.

+0

Câu trả lời hay. Ngoài ra, ít mã hơn nếu bạn tạo một phương thức và sau đó là một dòng mã trên mỗi khu vực. – CRice

4

tôi làm cho giải pháp này:

AreaUtils.cs

using System; 
    using System.Web.Mvc; 
    using System.Web.Routing; 

    namespace SledgeHammer.Mvc.Site 
    { 
     public static class Utils 
     { 
       public static void RegisterArea<T>(RouteCollection routes, 
    object state) where T : AreaRegistration 

      { 
       AreaRegistration registration = 
    (AreaRegistration)Activator.CreateInstance(typeof(T)); 

        AreaRegistrationContext context = 
    new AreaRegistrationContext(registration.AreaName, routes, state); 

        string tNamespace = registration.GetType().Namespace; 
        if (tNamespace != null) 
       { 
        context.Namespaces.Add(tNamespace + ".*"); 
       } 

       registration.RegisterArea(context); 
      } 
     } 

    } 

Trong global.asax:

Utils.RegisterArea<SystemAreaRegistration>(RouteTable.Routes, null); 
Utils.RegisterArea<ClientSitesAreaRegistration>(RouteTable.Routes, null); 

//AreaRegistration.RegisterAllAreas(); do not dublicate register areas 

Không có thay đổi requred đến mã số đăng ký khu vực tạo ra. Tôi cũng sử dụng lệnh tùy chỉnh trong các tuyến đường để lọc các tuyến đường theo loại miền theo yêu cầu (miền hệ thống hoặc trang web của người dùng).

Đây là đăng ký khu vực của tôi làm ví dụ:

namespace SledgeHammer.MVC.Site.Areas.System 
{ 
    public class SystemAreaRegistration : AreaRegistration 
    { 
     public override string AreaName 
     { 
      get { return "System"; } 
     } 

     public override void RegisterArea(AreaRegistrationContext context) 
     { 
      context.MapRoute(
       "System_Feedback", 
       "Feedback", 
       new { controller = "Feedback", action = "Index" } 
      ); 
      context.MapRoute(
       "System_Information", 
       "Information/{action}/{id}", 
       new { controller = "Information", action = "Index", id = UrlParameter.Optional } 
      ); 
     } 
    } 
} 



namespace SledgeHammer.MVC.Site.Areas.ClientSites 
{ 
    public class ClientSitesAreaRegistration : AreaRegistration 
    { 
     public override string AreaName 
     { 
      get { return "ClientSites"; } 
     } 

     public override void RegisterArea(AreaRegistrationContext context) 
     { 
      context.MapRoute(
       "ClientSites_default", 
       "{controller}/{action}/{id}", 
       new { controller = "Site", action = "Index", id = UrlParameter.Optional }, 
       new { Host = new SiteInGroups("clients") } 
      ); 
     } 
    } 
} 
+0

lớp util của bạn là tuyệt vời bởi vì nó chỉ ra bạn cần thêm không gian tên cho các khu vực nếu không các routs sẽ không được liên kết với bộ điều khiển –

4

Để tham khảo,

Trong MVC3 (không biết về MVC2) khi bạn chỉ muốn để lập bản đồ gốc để một khu vực cụ/điều khiển bạn chỉ đơn giản là có thể sử dụng một tuyến đường toàn cầu. Chỉ cần nhớ chỉ định không gian tên/khu vực.

routes.MapRoute(
     "CatchRoot", "", 
     new { controller = "SITEBLOG-CONTROLLER-NAME", action = "Index"} 
    ).DataTokens.Add("area", "SITE-AREA-NAME"); 
+0

+1 - Đây là một giải pháp tốt đẹp bởi vì nó cho phép mọi thứ được nhóm vào các khu vực nhưng khu vực để phục vụ như là điểm bắt đầu với URL sạch hơn. –

+0

Hoạt động hoàn hảo! Cho phép tôi có tất cả các bộ điều khiển trong các khu vực thay vì các khu vực đặc biệt và khu vực thực tế. Đối với bất kỳ ai muốn như vậy, hãy đăng ký tuyến đường mặc định trong cấu hình tuyến đường. – FDIM

Các vấn đề liên quan