2014-10-08 13 views
6

Tôi đang cố triển khai định tuyến thay thế trong ứng dụng web MVC 5 của mình.Định tuyến thay thế MVC không thành công với tham số tùy chọn

Tôi có mã điều khiển:

namespace MyMvcProject.Web.Controllers 
{ 
    [RoutePrefix("account")] 
    public class AccountController : Controller { 


     [Route("{param}")] 
     [Authorize] 
     public ActionResult Index(string param = null) { 

... 

mà hoạt động tuyệt vời khi đánh url: http://example.com/account/testparam. Tuy nhiên, tôi muốn có giá trị param làm thông số tùy chọn.

Tôi đã thử thay đổi [Route("{param}")] thành [Route("{param}*")] nhưng sau đó không bao giờ nhập phương thức Index(). Tôi cũng đã thử thay đổi nó thành [Route("{param:string=Test}")] nhưng tôi gặp lỗi thời gian chạy định tuyến với cụm từ string.

My RoutConfig.cs chứa:

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

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

Có ai có bất kỳ ý tưởng làm thế nào tôi có thể buộc Index() để có một tham số tùy chọn sử dụng cú pháp định tuyến thay thế này? Nó khá hữu ích trong các phần khác của ứng dụng của tôi, vì vậy tôi muốn giữ các trang trí RoutePrefixRoute.

CẬP NHẬT

tôi vẫn đang cố gắng để con số này ra, vì vậy tôi đã thay đổi trang trí tuyến đường của tôi để [Route("{param:int=0}")] và constructor của tôi để public ActionResult Index(int id) và nó hoạt động như mong đợi (ví dụ, http://example.com/account cư xử như thể http://example.com/account/0 đã được nhập. Đây chính là điều tôi muốn, chỉ sử dụng kiểu dữ liệu string

Khi tôi thay đổi trang trí để:. [Route("{id:string=\"\"}")] và các nhà xây dựng để public ActionResult Index(string id) và tôi thấy lỗi runtime:

The inline constraint resolver of type 'DefaultInlineConstraintResolver' was unable to resolve the following inline constraint: 'string'.

Trả lời

6

Tìm câu trả lời here. Tôi cần phải thực hiện param có thể sử dụng được bằng cách sử dụng ?.

[Route("{param?}")] 
[Authorize] 
public ActionResult Index(string param = null) { 
    ... 
} 

Hy vọng điều này sẽ giúp người khác trong tương lai. Không có nhiều tài liệu tham khảo mà tôi có thể tìm thấy về chủ đề này.

6

@ Brett's câu trả lời là rất tốt: thêm ? vào tham số trong thuộc tính Tuyến đường và sau đó cung cấp giá trị mặc định trong chữ ký Hành động cho phép tham số đó là tùy chọn.

Và đây là một bài viết tuyệt vời từ Mike Wasson trên Attribute Routing in Web API 2, bao gồm một phần về thông số tùy chọn.

Mike cũng nói về việc áp dụng nhiều trở ngại, và nói:

You can apply multiple constraints to a parameter, separated by a colon.

[Route("users/{id:int:min(1)}")] 
    public User GetUserById(int id) { ... } 

mà cũng làm việc tuyệt vời ... cho đến khi bạn muốn nhiều trở ngại một tham số tùy chọn.

Như chúng ta đã biết, áp dụng ? cho phép tham số là tùy chọn.Vì vậy, lấy ví dụ trên, người ta có thể giả định rằng

[Route("users/{id:int?:min(1)}")] 
public User GetUserById(int id = 1) { ... } 

chế các tham số id là số nguyên lớn hơn 0 hoặc để trống (trong trường hợp này mặc định là 1 được sử dụng). Trên thực tế, chúng tôi nhận được thông báo lỗi:

The inline constraint resolver of type 'DefaultInlineConstraintResolver' was unable to resolve the following inline constraint: 'int?'.

Nó chỉ ra rằng thứ tự của những hạn chế vấn đề! Đơn giản chỉ cần đặt các hạn chế tùy chọn ?sau tất cả các ràng buộc khác cung cấp cho các hành vi dự định

[Route("users/{id:min(1):int?}")] 
public User GetUserById(int id = 1) { ... } 

này hoạt động trong hơn 2 trở ngại là tốt, ví dụ

[Route("users/{id:min(1):max(10):int?}")] 
public User GetUserById(int id = 1) { ... } 
+1

Mẹo hữu ích về đơn đặt hàng. – Nicholi

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