2015-10-15 23 views
14

Vì vậy, tôi đang chuyển đổi một khu vực từ việc sử dụng AreaRegistration sang sử dụng Định tuyến Thuộc tính. Tôi đang chạy vào một vấn đề mà dường như được gây ra bởi thứ tự mà các tuyến đường được nạp vào bảng định tuyến. Tôi đã giải quyết vấn đề trong AreaRegistration bằng cách tải trong tuyến đường có vấn đề cuối cùng, do đó, chỉ khi tất cả các tuyến đường khác không phù hợp với tuyến đường đó sẽ được kết hợp. Với Định tuyến Thuộc tính, điều này dường như không thể thực hiện được. Tôi có thông số Order khi tạo một route, nhưng điều này không ảnh hưởng đến cách mọi thứ chạm vào bảng định tuyến ngoại trừ rất hẹp.Có thể thay đổi thứ tự các tuyến trong bảng định tuyến khi sử dụng định tuyến thuộc tính không?

Đây là con đường tôi có trong tập tin AreaRegistration:

context.MapRoute(
    name: "ActionItems_home", 
    url: "ActionItems/{group}/{statuses}/{overdueOnly}", 
    defaults: new { controller = "Home", action = "Index", group = "All", statuses = "New,Open", overdueOnly = false }, 
    namespaces: new string[] { "IssueTracker.Areas.ActionItems.Controllers" } 
    ); 

Bây giờ, khi tôi cố gắng để chuyển đổi này để Attribute Routing điều duy nhất mà đến gần làm việc là:

[Route("", Order = 4)] 
[Route("{group:regex(^(?!Item|DecisionLogs))?}", Order = 3)] 
[Route("{group:regex(^(?!Item|DecisionLogs))}/{statuses=New,Open?}", Order = 2)] 
[Route("{group:regex(^(?!Item|DecisionLogs))}/{statuses=New,Open}/{overdueOnly:bool=false?}", Order = 1)] 

Note rằng tôi phải đặt trong regex bởi vì nếu không thì bộ điều khiển Item không được gọi - thay vào đó, tôi kết thúc với chuỗi 'Item' được truyền vào như tham số group. Nhưng regex không đặc biệt giúp đỡ về cách kết thúc của URL được hiển thị.

Tôi sẽ như để tham số tùy chọn bị chặn trong URL trừ khi chúng không mặc định. Tôi đã thử xác định các tham số như là tùy chọn, với các giá trị mặc định, và cả hai tùy chọn và với các giá trị mặc định. Không ai trong số họ dường như thực sự làm các trick.

Giải pháp hiện tại ít nhất là trình bày URL không có chuỗi truy vấn, nhưng chúng bao gồm các thông số tùy chọn và làm mọi thứ xấu xí. Hiện tại, tôi chỉ đơn giản là để lại các tuyến đường nghiêm trọng được xác định trong các tệp AreaRegistration & không được trang trí với các đoạn [Route()].

+0

Xem http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#order –

+0

Cảm ơn vì điều đó, Amir . Có vẻ như thuộc tính RouteOrder có sẵn cho lớp ApiController ... trong một số phiên bản nhất định của Bộ điều khiển API Web. Nó không có sẵn, tuy nhiên, để một bộ điều khiển kế thừa từ lớp 'System.Web.Mvc.Controller', đó là nơi tôi đang chạy vào vấn đề. Việc thay đổi sự kế thừa của bộ điều khiển thành 'System.Web.Http.ApiController' không giúp được gì, vì ApiController không có tham số RouteOrder trong MVC5 (cộng với, điều này sẽ phá vỡ bộ điều khiển). –

+0

Âm thanh như bạn có thể không có trên ASP.NET MVC 5. Tôi nghĩ rằng định tuyến thuộc tính chỉ được giới thiệu trong 5. http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing- in-asp-net-mvc-5.aspx –

Trả lời

3

Vấn đề thực sự của bạn là cách định cấu hình tuyến đường ban đầu của bạn bằng Định tuyến thuộc tính. Vấn đề đặt hàng chỉ là một tác dụng phụ của việc cấu hình một số tuyến thay vì một tuyến. Để đạt được cấu hình mong muốn của bạn, bạn có thể tạo một RouteAttribute tùy chỉnh và làm bất cứ điều gì bạn cần bên trong.

public class OptionalsRouteAttribute : RouteFactoryAttribute 
{ 
    private object _defaults; 

    public OptionalsRouteAttribute(string template, object defaults) 
     : base(template) 
    { 
     Defaults = defaults; 
    } 

    [...] 
} 

Bạn có thể thấy một sample hereoriginal RouteFactoryAttribute nguồn để tham khảo

Tôi sợ rằng tôi không có thời gian ngay bây giờ để cung cấp việc thực hiện thực tế bản thân mình, nhưng tôi hy vọng điều này sẽ dẫn bạn đến Đúng hướng.

CẬP NHẬT Tôi đã dùng thử này và giải pháp rất đơn giản sau đây hoạt động như mong đợi. Việc triển khai thuộc tính của tôi là cụ thể đối với mẫu bạn cung cấp với thông số nhóm, trạng thái và thông số quá hạn, nhưng bạn có thể tạo một giải pháp chung chung hơn bao gồm tất cả các trường hợp của bạn (bạn cũng cần thêm không gian tên)

public class OptionalsRouteAttribute : RouteFactoryAttribute 
{ 
    public OptionalsRouteAttribute(string template, string group, string statuses, bool overdueOnly) 
     : base(template) 
    { 
     var defaults = new RouteValueDictionary 
     { 
      {"group", @group}, 
      {"statuses", statuses}, 
      {"overdueOnly", overdueOnly} 
     }; 
     Defaults = defaults; 
    } 

    public override RouteValueDictionary Defaults { get; } 

} 

Sau đó, trong Bộ điều khiển:

[OptionalsRoute("ActionItemsAttribute/{group}/{statuses}/{overdueOnly}", "All", "New,Open", false)] 
    public ActionResult AttributeRouting(string group, string statuses, bool overdueOnly) 
    { 
     ViewBag.Message = $"Attribute Routing: Group [{@group}] - Statuses [{statuses}] - overdueOnly [{overdueOnly}]"; 
     return View("Index"); 
    } 

Và nó hoạt động hoàn toàn giống như cấu hình định tuyến ban đầu của bạn, nhưng sử dụng một thuộc tính.

2

ASP.NET MVC là mã nguồn mở và nó được thiết kế theo cách mà mỗi lớp có thể được thay thế bằng của riêng bạn.Bạn có thể download the source code, tìm phần có vấn đề và tìm hiểu cách hoạt động của nó. Cuối cùng thay thế bằng mã riêng nếu cần.

git clone https://git01.codeplex.com/aspnetwebstack.git 

Nếu bạn tải về mã nguồn này, bạn sẽ tìm thấy một lớp System.Web.Mvc.RouteAttribute với phương pháp CreateRoute. Tôi không chắc chắn, nhưng nó có thể được bằng cách nào đó kết nối với vấn đề của bạn.

RouteEntry IDirectRouteFactory.CreateRoute(DirectRouteFactoryContext context) 
{ 
    Contract.Assert(context != null); 

    IDirectRouteBuilder builder = context.CreateBuilder(Template); 
    Contract.Assert(builder != null); 

    builder.Name = Name; 
    builder.Order = Order; 
    return builder.Build(); 
} 

Tìm tham chiếu trên giao diện này, bạn có thể tìm lớp DefaultDirectRouteProvider.

Một cách tiếp cận khác là bạn có thể cố gắng tìm việc "Đặt hàng" trong dự án. Nếu bạn bỏ qua kiểm tra, không có quá nhiều lần xuất hiện và một số nằm trong các lớp routeSomething.

Bạn có thể bỏ chọn "Chỉ mã của tôi" trong Visual Studio và gỡ lỗi mã ASP.NET MVC.

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