2009-07-18 31 views
30

phép nói rằng bạn có một phương pháp hành động để trưng bày sản phẩm trong một giỏ mua hàngLàm thế nào để ngăn chặn Url.RouteUrl (...) từ kế thừa các giá trị đường từ yêu cầu hiện tại

// ProductsController.cs 
public ActionMethod Index(string gender) { 

     // get all products for the gender 
} 

Ở những nơi khác, trong quảng cáo tiêu đề đó là hiển thị trên tất cả các trang web mà bạn đang sử dụng Url.RouteUrl để tạo liên kết HREF đến các trang khác trên trang web:

<a href="<%= Url.RouteUrl("testimonials-route", new { }) %>" All Testimonials </a> 

testimonials-route này được định nghĩa trong global.ascx bằng con đường đầu tiên dưới đây. Lưu ý rằng lệnh gọi ở trên đến RouteUrl không cung cấp số gender, nhưng tuyến đường được xác định với mặc định là 'trung lập', vì vậy chúng tôi dự kiến ​​sẽ được gọi Testimonials.Index ("trung lập").

routes.MapRoute(
    "testimonials-route", 
    "testimonials/{gender}", 
    new { controller = "Testimonials", action = "Index", gender = "neutral" }, 
    new { gender = "(men|women|neutral)" } 
); 

routes.MapRoute(
    "products-route", 
    "products/{gender}", 
    new { controller = "Products", action = "Index", gender = (string)null }, 
    new { gender = "(men|women|neutral)" } 
); 

Nếu ai đó truy cập trang /products/women chúng tôi nhận được một HREF để /testimonials/women Nếu ai đó truy cập trang /products sau đó chúng tôi nhận được một HREF rỗng (cuộc gọi đến RouteUrl trả về null).

Nhưng điều đó không có ý nghĩa gì? testimonials-route được cho là mặc định là 'neutral' đối với chúng tôi nếu chúng tôi không cung cấp giá trị tuyến đường cho nó?

gì hóa ra đang xảy ra là Url.RouteUrl(routeName, routeValues) mở rộng helper đầu tiên sẽ nhìn vào thông số routeValues của nó cho một giá trị gender tuyến đường và nếu nó không tìm thấy nó trong từ điển mà nó sẽ xem xét các URL hiện tại mà chúng ta đang ở trên (hãy nhớ rằng Url là một đối tượng UrlHelper có ngữ cảnh của yêu cầu hiện tại có sẵn cho nó).

Điều này có tác dụng tốt cho chúng tôi liên kết đến lời chứng thực của nam giới nếu chúng tôi đang ở trên trang sản phẩm dành cho nam giới, nhưng điều đó có thể không phải là điều chúng tôi muốn nếu chúng tôi không vượt qua giá trị trong cuộc gọi RouteUrl. được chỉ định 'trung lập' làm mặc định trong tệp global.asax.cs.

Trong trường hợp chúng tôi truy cập /products/, chúng tôi đã kích hoạt tuyến đường 'products-route' và phương pháp Products(null) đã được gọi. Cuộc gọi đến Url.RouteUrl() thực sự thừa kế giá trị null này cho gender khi chúng tôi tạo URL bằng cách sử dụng testimonials-route. Mặc dù chúng tôi đã chỉ định mặc định cho gender trong 'testimionials-route 'nó vẫn sử dụng giá trị null này khiến tuyến đường bị lỗi và RouteUrl trả về giá trị rỗng. [lưu ý: tuyến đường không thành công vì chúng tôi có ràng buộc về (nam | nữ | trung tính) và không phù hợp với điều đó]

Thực tế sẽ đáng sợ hơn - trong 'bộ điều khiển' và 'hành động' có thể được kế thừa trong theo cùng một cách. Điều này có thể dẫn đến các URL được tạo ra hoàn toàn cho bộ điều khiển sai ngay cả khi gọi RouteUrl (...) với tên tuyến đường rõ ràng có bộ điều khiển mặc định.

Trong trường hợp này một khi bạn đã tìm ra nó, bạn có thể sửa chữa nó khá dễ dàng theo nhiều cách, nhưng nó có thể trong các trường hợp khác gây ra một số hành vi nguy hiểm. Điều này có thể là do thiết kế, nhưng nó chắc chắn đáng sợ.

+0

thêm tiền thưởng một năm rưỡi sau câu hỏi ban đầu vì (a) tôi muốn biết liệu khuôn khổ hiện có thực hiện điều này cho tôi không và (b) tôi rất tò mò tại sao điều này chỉ có 2 upvotes. nghĩ rằng nó sẽ là một vấn đề phổ biến vì vậy tự hỏi nếu tôi đang làm điều gì đó sai trái! –

+0

điều này đã khởi động tính năng khởi động của tôi, vì thẻ {domain} thiếu giá trị, nhưng hệ thống được cho là sẽ tự động cung cấp. Khi tôi thay đổi điều này, nó đã hoạt động. –

+0

tại sao bạn không chỉ gọi RenderUrl như: '" '- vậy, không có gì bị ghi đè . – Gerwald

Trả lời

26

Giải pháp của tôi là thế này:

Một phương pháp HtmlExtension helper:

public static string RouteUrl(this UrlHelper urlHelper, string routeName, object routeValues, bool inheritRouteParams) 
    { 
     if (inheritRouteParams) 
     { 
      // call standard method 
      return urlHelper.RouteUrl(routeName, routeValues); 
     } 
     else 
     { 
      // replace urlhelper with a new one that has no inherited route data 
      urlHelper = new UrlHelper(new RequestContext(urlHelper.RequestContext.HttpContext, new RouteData())); 
      return urlHelper.RouteUrl(routeName, routeValues); 
     } 
    } 

bây giờ tôi có thể làm:

Url.RouteUrl('testimonials-route', new { }, false) 

và biết chắc chắn nó sẽ luôn luôn cư xử theo cùng một cách không có vấn đề bối cảnh.

Cách hoạt động của nó là lấy UrlHelper hiện tại và tạo một cái mới có 'RouteData' trống. Điều này có nghĩa là không có gì để kế thừa từ (ngay cả một giá trị null).

+0

trong khi tôi tốt với giải pháp của tôi - Tôi ước có một cách để thực thi nó trên toàn cầu, và không phải nhớ luôn luôn sử dụng tình trạng quá tải này. hy vọng MVC4 sẽ kiểm soát tốt hơn điều này. –

+0

Tôi chỉ gặp vấn đề tương tự. Điều này rất hữu ích! Tôi đã nghĩ đến việc mở rộng phương thức HtmlHelper.RouteLink để làm điều tương tự cho các liên kết, nhưng tôi đang gặp khó khăn trong việc sắp xếp cú pháp để khởi tạo một HtmlHelper mới. – goombaloon

+0

Đây là một giải pháp tốt. Đối với chúng tôi, các liên kết này đều nằm trong cùng một khung nhìn, vì vậy tôi vừa tạo ra UrlHelper mới dưới dạng biến và sử dụng biến đó trong phần thay vì thuộc tính Url chuẩn. –

2

Có lẽ tôi đang thiếu một cái gì đó ở đây, nhưng tại sao không thiết lập nó như thế này:

Trong tuyến Asax toàn cầu của bạn, tạo ra hai tuyến đường:

routes.MapRoute(
    "testimonial-mf", 
    "Testimonials/{gender}", 
    new { controller = "Testimonials", action = "Index" } 
); 

routes.MapRoute(
    "testimonial-neutral", 
    "Testimonials/Neutral", 
    new { controller = "Testimonials", action = "Index", gender="Neutral" } 
); 

Sau đó, sử Url.Action thay vì Url .RouteUrl:

<%= Url.Action("Testimonials", "Index") %> 
<%= Url.Action("Testimonials", "Index", new { gender = "Male" }) %> 
<%= Url.Action("Testimonials", "Index", new { gender = "Female" }) %> 

trong đó, trên máy tính của tôi giải quyết để các url sau:

/Testimonials/Neutral 
/Testimonials/Male 
/Testimonials/Female 

Tôi không chắc đây có phải là giải pháp có thể chấp nhận được hay không, nhưng đó là giải pháp thay thế, phải không?

+0

không may (hoặc may mắn có lẽ!) Vấn đề không phải là trong phân tích cú pháp và định tuyến của URL. hoạt động hoàn hảo như mong đợi - vì vậy tuyến đường đầu tiên của bạn ở đây là đủ (nếu bạn thêm thông số mặc định). đó là việc tạo URL thực tế khi các giá trị tuyến đường hiện có được thừa hưởng bất ngờ. giải pháp của tôi tôi đã sử dụng trong hơn một năm - nó chỉ gây phiền nhiễu khi bạn cần sử dụng các tình trạng quá tải khác của RouteUrl hoặc RouteLink và bạn cần phải tạo ra một tấn quá tải phương thức. cảm ơn vì câu trả lời –

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