2012-03-01 46 views
6

Tôi đang xây dựng một ứng dụng Web báo cáo đơn giản để hiển thị báo cáo bằng ASP.NET MVC3 + WebForms. Bản thân các báo cáo được kiểm soát bởi ReportViewer ASP.NET WebForms, nhưng tôi muốn sử dụng ASP.NET MVC để tạo mục nhập tham số.ASP.NET MVC + WebForms - xung đột tuyến đường

Tôi muốn có tất cả các yêu cầu tuân theo lược đồ định tuyến mặc định của '~/{controller}/{action}/{parameters}', ngoại trừ các yêu cầu cho ~/Report, sẽ chuyển đến báo cáo kết xuất WebForm. Cách thích hợp để làm điều này là gì?

Mở rộng một chút ..

Tôi có hai tuyến đường trong Global.asax.cs - mặc định một và một cho các trang WebForms.

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapRoute(
     "Default", // Route name 
     "{controller}/{action}/{id}", // URL with parameters 
     new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
    ); 

    routes.MapPageRoute("report-rendering", "Report", "~/Render.aspx"); 
} 

Các URL nhận được kết xuất tốt, nhưng vấn đề với điều này là khi yêu cầu đến, con đường đầu tiên cũng ăn các URL cho một thứ hai, tức là ~/Report?id=7 cố gắng gọi phương thức Index trên ReportController (không tồn tại).

Nếu tôi thay đổi nó sao cho 'báo cáo-vẽ' đường đến trước con đường 'mặc định', như vậy:

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapPageRoute("report-rendering", "Report", "~/Render.aspx"); 

    routes.MapRoute(
     "Default", // Route name 
     "{controller}/{action}/{id}", // URL with parameters 
     new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
    ); 
} 

Bây giờ cuộc gọi đến Html.ActionLink() làm cho URL không chính xác, ví dụ:

`@Html.ActionLink("Report list", "Index", "ReportList")` 

Renders

`http://localhost:49910/Report?action=Index&controller=ReportList` 

workaround hiện tại của tôi đặt con đường 'Default' đầu tiên, trong khi thêm một hạn chế regex để bỏ qua yêu cầu 'Báo cáo' điều khiển, như vậy:

routes.MapRoute(
    "Default", // Route name 
    "{controller}/{action}/{id}", // URL with parameters 
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 
    new { controller = @"(?!report$).*" } 
); 

này không cảm thấy sạch sẽ. Một lần nữa, cách thích hợp để làm điều này là gì?

Ngoài ra, tôi chưa quyết định cách tôi sẽ chuyển các tham số cho biểu mẫu hiển thị: Tôi có thể sử dụng cả tham số truy vấn hoặc BÀI chúng. Tôi đoán rằng các tham số truy vấn linh hoạt hơn. Thực hành tốt nhất ở đây là gì?

EDIT:

Trong khi nghiên cứu câu trả lời bằng cách @LeftyX, có vẻ như tôi đã tìm thấy một câu trả lời. Để báo P. Haack từ chương của ông Routing trong Professional ASP.NET MVC 3 (Tuyến đường được đặt tên, Chương 9, trang 233):

... Sử dụng tên cho tất cả các tuyến đường của bạn và luôn sử dụng tên đường khi tạo URL . Hầu hết thời gian, cho phép Định tuyến phân loại tuyến đường nào mà bạn muốn sử dụng để tạo URL thực sự rời khỏi cơ hội, điều này không phải là điều mà cũng phù hợp với nhà phát triển điều khiển bị ám ảnh cưỡng chế. Khi tạo một URL, bạn thường là biết chính xác tuyến đường nào bạn muốn liên kết đến, vì vậy bạn cũng có thể chỉ định nó theo tên.

Phần được đề cập thảo luận về tình huống rất giống với tình huống tôi đã mô tả.

Nhưng vì Html.ActionLink() không bị quá tải với thông số tên tuyến, điều này có nghĩa là tôi không thể sử dụng nó một cách đáng tin cậy ở bất kỳ đâu trong toàn bộ ứng dụng nếu có lộ trình như thế này?

Trả lời

1

Đây là giải pháp tốt nhất mà tôi đã tìm ra.
Tôi đã đăng ký lộ trình của tôi với MapPageRoute (tôi đã tập hợp trang Báo cáo của tôi dưới một thư mục có tên Báo cáo)

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapPageRoute(
      "report-rendering", 
      "Report/{id}", 
      "~/Reports/Report.aspx" 
     ); 

     routes.MapRoute(
      "Default", // Route name 
      "{controller}/{action}/{id}", // URL with parameters 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
      ); 
} 

tôi đã tạo ra liên kết của tôi sử dụng RouteLink vì vậy bạn có thể xác định lộ trình sử dụng:

@Html.RouteLink("Report list", "report-rendering", new { id = 7 }) 

và tôi có thể nhận được id trong trang WebForm của tôi như thế này:

protected void Page_Load(object sender, EventArgs e) 
{ 
    var id = Page.RouteData.Values["id"] as string; 
} 

Hy vọng điều đó sẽ hữu ích.

CẬP NHẬT:

tôi đã tạo ra một phương pháp mở rộng để làm cho cuộc sống của bạn dễ dàng hơn:

public static class ExtensionMethods 
{ 
    public static MvcHtmlString WebFormActionLink(this HtmlHelper htmlHelper, string linkText, string ruoteName, object routeValues) 
    { 
     var helper = new UrlHelper(htmlHelper.ViewContext.RequestContext); 

     var anchor = new TagBuilder("a"); 
     anchor.Attributes["href"] = helper.RouteUrl(routeName, routeValues); 
     anchor.SetInnerText(linkText); 
     return MvcHtmlString.Create(anchor.ToString()); 
    } 
} 

tốt nhất có thể đã được sử dụng ActionLink thay vì WebFormActionLink nhưng tôi có vấn đề với chữ ký và tôi không phải là một chuyên gia về điều này.

+0

Cảm ơn câu trả lời của bạn. Tôi thấy những gì bạn đã làm ở đó. Vì bạn đã thêm tham số {id}, các cuộc gọi .RouteLink() mà không cung cấp giá trị cho {id} không còn khớp với tuyến đường nữa. Tuy nhiên, tạo tuyến đường trong khi chỉ định tham số id sẽ khớp với tuyến đường này. Điều này: @ Html.ActionLink ("Trang 1", "Trang", "Trang chủ", mới {id = 1}, null) Sẽ tạo điều này: http: // localhost: 49910/Report/1? = Trang & bộ điều khiển = Trang chủ Đó không phải là điều bạn mong đợi, đúng không? –

+0

@ghostskunks: Tôi biết. Tôi e rằng bạn phải sử dụng RouteLink để tạo liên kết cho WebForms hoặc bạn có thể thử mở rộng ActionLink. – LeftyX

+0

@ghostskunks: Tôi đã cố gắng để đặt một cái gì đó với nhau (cập nhật câu trả lời) nhưng, như tôi đã nói, tôi không phải là một chuyên gia. Nó chỉ là một ý tưởng. – LeftyX

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