2010-06-23 5 views
5

Tôi đang cố gắng tạo URI trông giống như thế này: http://hostname/mobile/en/controller/action cho điện thoại di động HOẶC http://hostname/en/controller/action cho máy tính để bàn (không di động).Tuyến đường luôn đi tới bản đồ đầu tiên

My Route bảng hiện trông như thế này (Global.asax.cs)

 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     routes.MapRoute(
      "Mobile", // Route name 
      "mobile/{language}/{controller}/{action}/{id}", // URL with parameters 
      new { language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 
      new { language = @"en|us" } // validation 
     ); 
     routes.MapRoute(
      "Default", // Route name 
      "{language}/{controller}/{action}/{id}", // URL with parameters 
      new { language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 
      new { language = @"en|us" } // validation 
     ); 

Vấn đề xảy ra khi tôi cố gắng để làm một return RedirectToAction("Add", "User"); Nó luôn luôn chuyển hướng trình duyệt máy tính để bàn /en/User/List-/mobile/en/User/Add khi tôi muốn nó để đi đến /en/User/Add. Phiên bản di động hoạt động chính xác nhưng tôi tin rằng điều này là do tuyến đường "Di động" đầu tiên luôn được xem là tuyến phù hợp ngay cả khi nó không có/di động/lúc khởi động.

Tôi đang cố gắng sử dụng cùng một bộ điều khiển cho cả hai phiên bản nhưng bị kẹt ở đó luôn chuyển hướng đến tuyến đường Di động. Điều này có nghĩa là RedirectToRoute không hoàn hảo vì tôi muốn các tuyến động.

Cảm ơn sự giúp đỡ của bạn.

Trả lời

2

Vấn đề chính là tuyến đường-giá trị mà bạn cung cấp khớp với cả hai tuyến đường, có nghĩa là nó sẽ đi theo tuyến đầu tiên (di động).

Bạn có thể chọn tuyến đường để sử dụng theo cách thủ công bằng cách chuyển hướng đến các tuyến thay cho hành động.

return RedirectToRoute("Mobile", new { 
    language = "en", controller = "User", action = "Get", id = 20 
}); 

cho điện thoại di động hoặc

return RedirectToRoute("Default", new { 
    language = "en", controller = "User", action = "Get", id = 20 
}); 

cho tuyến đường mặc định của bạn.

Tuy nhiên, điều này khiến bạn gặp vấn đề mới: lấy tên của tuyến đường hiện tại. Như đã thấy trong ví dụ, đề cập đến các tuyến đường được đặt tên là rất tốt. Lấy tên của tuyến đường hiện đang sử dụng tuy nhiên dường như là không thể. Sử dụng một hack như nhìn vào URI hiện tại rõ ràng là không mong muốn. Bên cạnh đó là xấu xí (một hack) nó cũng có thể dẫn đến rất nhiều bản sao mã.

tuy nhiên còn có một khả năng bổ sung thêm giá trị cho các tuyến đường có thể dễ dàng thu được từ điều khiển của bạn (hoặc xem):

routes.MapRoute(
    "Mobile", // Route name 
    "mobile/{language}/{controller}/{action}/{id}", // URL with parameters 
    new { routeName = "Mobile", language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 
    new { language = @"en|us" } // validation 
); 
routes.MapRoute(
    "Default", // Route name 
    "{language}/{controller}/{action}/{id}", // URL with parameters 
    new { routeName = "Default", language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 
    new { language = @"en|us" } // validation 
); 

Bây giờ từ mã của bạn, bạn có thể chuyển hướng đến các tuyến đường hiện tại bằng cách sử dụng các giá trị cung cấp từ con đường riêng của mình:

return RedirectToRoute(RouteData.Values["routeName"], new { 
    language = "en", controller = "User", action = "Get", id = 20 
}); 

Bây giờ nếu bạn muốn thực hiện này hoàn toàn lạ mắt, bạn thậm chí có thể làm cho một phương pháp mở rộng ra những điều này:

public static class ControllerExtensions { 
    public static RedirectToRouteResult CustomRedirectToRoute(this Controller controller, string controllerName, string actionName, object routevalues) { 
     return CustomRedirectToRoute(controller, controllerName, actionName, new RouteValueDictionary(routevalues)); 
    } 

    public static RedirectToRouteResult CustomRedirectToRoute(this Controller controller, string controllerName, string actionName, RouteValueDictionary routevalues) { 
     routevalues = routevalues ?? new RouteValueDictionary(); 
     routevalues.Add("controller", controllerName); 
     routevalues.Add("action", actionName); 
     return new RedirectToRouteResult(controller.RouteData.Values["routeName"] as string, routevalues); 
    } 
} 

Hy vọng điều này cung cấp giải pháp tốt cho vấn đề của bạn!

+0

Cảm ơn René giống như những gì tôi đã hy vọng làm. Bạn có thể cho tôi biết nơi tốt nhất là đặt phương pháp mở rộng không? – Adrian

+1

Đặt lớp tĩnh ControllerExtensions bất cứ nơi nào bạn muốn. Và trong bộ điều khiển bạn muốn sử dụng chuyển hướng, hãy đảm bảo bao gồm không gian tên mà lớp tiện ích mở rộng. Sau đó, bất kỳ vị trí nào trong bộ điều khiển của bạn, bạn có thể sử dụng this.CusomRedirectToRoute ("Home", "Index", routeValues); Bạn cũng có thể thêm một phương thức tiện ích mở rộng khác có giá trị là routeValues ​​nếu bạn muốn. –

+0

Nếu bạn muốn dọn dẹp nó, phần sau của bình luận của tôi có thể được thay thế bởi hệ thống gọn gàng và sạch sẽ để lấy tên của tuyến đường như được mô tả trong bài đăng này: http://stackoverflow.com/questions/363211/how -can-i-get-the-route-tên-trong-bộ điều khiển-trong-asp-net-mvc –

0

Hey bạn có thể muốn kiểm tra bộ điều khiển nhóm trong bài viết này: http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx

Hy vọng nó sẽ là hữu ích. Chúng tôi sử dụng công việc này và nó đang hoạt động tốt

+0

Cảm ơn bạn đã liên kết. Đó là một cái gì đó để xem xét nếu tôi mở rộng dự án. – Adrian