2009-09-24 9 views
7

Tôi có một ứng dụng ở đây với sự kết hợp của biểu mẫu web và mvc. Tôi chỉ định định tuyến như bên dướiHtml.ActionLink xây dựng liên kết sai khi một tuyến đường không phải là mvc được thêm

 routes.Add("AspxRoute", new Route("Upload/New", new WebFormRouteHandler<Page>("~/Uploads.aspx"))); 

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

Vì vậy, đường dẫn ảo để "Tải lên/Mới" thực sự ánh xạ tới trang biểu mẫu web aspx.

Nhưng vấn đề của tôi là Html.ActionLink ("Test", "điều khiển", "Action") bây giờ làm cho

/Upload/điều khiển mới? = Điều khiển & Action = Hành động

Sau khi xem mã nguồn MVC, tôi hiểu rằng đó là do ActionLink gọi tới RouteCollection.GetVirtualPath(requestContext, routeName, mergedRouteValues), trong đó routeName được để trống. Và bằng cách nào đó điều này mặc định để sử dụng các tuyến đường AspxRoute để xây dựng các url. Tôi đã cố gắng để thêm một tuyến đường trước khi "AspxRoute", nhưng có vẻ như nó luôn luôn mặc định để không phải là một bộ định tuyến mvc.

Làm cách nào để RouteCollection.GetVirtualPath hoạt động khi routeName rỗng? Và tại sao nó hành xử theo cách này cho trường hợp của tôi?

Làm cách nào để tạo một url chính xác? Tôi có cần phải viết một phần mở rộng Htmlhelper mới không?

Cheers

Trả lời

3

Hãy thử:

<%=Html.RouteLink("Test", "Default", new {controller = "Controller", action = "Action"})%> 

Sử dụng RouteLink thay vì ActionLink phép bạn chỉ định con đường bạn muốn sử dụng, mà trong trường hợp này là mặc định MVC đường lập bản đồ như trái ngược với các tùy chỉnh một Bạn đã thêm.

+0

Hi cảm ơn. Tôi biết RouteLink hoạt động, nhưng nó chỉ là một chút bất tiện! Tất cả các dây ma thuật. Tại sao ActionLink không hoạt động. –

+0

Nó chỉ chứa một chuỗi hơn ActionLink và câu hỏi ban đầu của bạn là "Làm cách nào để tạo một url chính xác?". Lý do tại sao điều này là cần thiết là WebFormRouteHandler của bạn cung cấp một "hợp lệ" tuyến đường phù hợp, và vì nó được thêm vào trước khi tuyến đường mặc định của bạn trong RouteTable nó được trả về đầu tiên. Nhưng dù sao, tôi đã thêm một câu trả lời khác có thể nhiều hơn theo ý thích của bạn. –

6

Một tùy chọn thay thế sẽ là thêm ràng buộc tùy chỉnh vào (các) WebFormRoute của bạn. Ví dụ, bạn có thể tạo một triển khai thực hiện IRouteConstraint để khớp với RouteDirection.IncomingRequest, sau đó sử dụng nó để đảm bảo tuyến đường bị bỏ qua bởi các tuyến do máy chủ tạo ra (như ActionLink) nhưng vẫn được sử dụng bởi các yêu cầu do khách hàng tạo ra. Một cái gì đó như:

public class IncomingOnlyRouteConstraint: IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     if (routeDirection == RouteDirection.IncomingRequest) 
     { 
      return true; 
     } 
     return false; 
    } 
} 

Và sau đó thêm các hạn chế đối với tuyến đường của bạn:

routes.Add("AspxRoute", new Route("Upload/New", null, 
          new RouteValueDictionary() { {"WebFormsConstraint", new IncomingOnlyRouteConstraint()} }, 
          new WebFormRouteHandler<Page>("~/Uploads.aspx"))); 

Tất nhiên bạn có thể thích thêm phong cách riêng của bạn hạn chế, điều này là khá hạn chế trên các tuyến đường mà thực hiện nó , nhưng nó chỉ là một ví dụ về một cách bạn có thể giải quyết vấn đề.

+0

Cảm ơn, tôi đã sử dụng câu trả lời này để khắc phục một câu hỏi khác của tôi. – JTew

+0

Tuyệt vời! Chính xác những gì tôi đang tìm kiếm! – gsobocinski

+1

Tôi rất tiếc là tôi có một ưu tiên để đưa ra câu trả lời này. –

2

Ngoài ra: Đảm bảo Tuyến đường mặc định của bạn là mục nhập LAST trong bảng định tuyến. Đó là một cách dễ dàng khác để kết hợp với loại liên kết hành động html mà bạn đang nhận được.

+0

Câu hỏi từ một thời gian dài trước đây vẫn nhận được câu trả lời :-) nếu bạn xem mã tôi đã đính kèm, đó là mục nhập cuối cùng trong bảng lộ trình. MVC.net đã đi một chặng đường dài, có thể tất cả đã thay đổi, tôi không biết! –

1

Tôi đã trải nghiệm cùng một điều mà các tuyến đường hoạt động chính xác "đến", nhưng Html.ActionLink() đã chọn sai tuyến đường. Tôi làm việc xung quanh nó bằng cách thêm một hạn chế con đường để các controller phải trống:

var constraints = new RouteValueDictionary() 
{ 
    { "controller", string.Empty } 
}; 

routes.Add(new Route("sso/server", null, constraints, new OpenIDServerRouteHandler())); 

routes.MapRoute(
    name: "Default", 
    url: "{controller}/{action}/{identity}", 
    defaults: new { controller = "Pages", action = "Home", identity = UrlParameter.Optional } 
); 

Kể từ khi "điều khiển" giá trị con đường bị hạn chế không có gì, một cuộc gọi đến ActionLink() kết thúc bỏ qua các tuyến đường. Hy vọng điều này sẽ giúp một ai đó!

1

Force giá trị mặc định lộ trình để không có điều khiển:

var routeDefaults = new RouteValueDictionary() { { "controller", null } }; 
routes.Add("RouteName", new Route("some/path", routeDefaults, new SomeHandler()));