2014-10-08 8 views
6

Próbuję wdrożyć alternatywne trasowanie w mojej aplikacji internetowej MVC 5.MVC Alternatywne trasowanie kończy się niepowodzeniem z opcjonalnym parametrem

mam kod kontrolera:

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


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

... 

który działa wspaniale, gdy uderzenie URL: http://example.com/account/testparam. Jednak chciałbym mieć wartość param jako parametr opcjonalny.

Próbowałem zmienić [Route("{param}")] na [Route("{param}*")], ale metoda Index() nigdy nie została wprowadzona. Próbowałem również zmienić go na [Route("{param:string=Test}")], ale pojawia się błąd runtime ruting z pojęciem string.

My RoutConfig.cs zawiera:

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 } 
      ); 
     } 

Czy ktoś ma jakiś pomysł jak mogę zmusić Index() mieć opcjonalny parametr przy użyciu tej alternatywnej składni routingu? Jest całkiem przydatny w innych częściach mojej aplikacji, więc chciałbym zachować dekoratory RoutePrefix i Route.

UPDATE

Ja wciąż próbuje dowiedzieć się tego, więc zmieniłem trasy dekorator do [Route("{param:int=0}")] i mojego konstruktora public ActionResult Index(int id) i działa zgodnie z oczekiwaniami (tzn http://example.com/account zachowuje się tak, jakby http://example.com/account/0 została wpisana. to jest dokładnie to, co chcę, tylko przy użyciu string typy danych

Kiedy zmienić dekorator. do: [Route("{id:string=\"\"}")] i konstruktora public ActionResult Index(string id) i widzę błąd wykonania:

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

Odpowiedz

6

Znaleziono odpowiedź here. Muszę uczynić param zerowalnym przy użyciu ?.

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

Mam nadzieję, że to pomoże komuś w przyszłości. Nie ma wielu referencji, które można znaleźć na ten temat.

6

@ Bretta odpowiedź jest wielki: dodawanie ? do parametru w atrybucie trasy, a następnie dostarczanie wartości domyślnej w podpisie działania pozwala że parametr jest opcjonalny.

Oto świetny artykuł Mike'a Wassona pod tytułem Attribute Routing in Web API 2, zawierający fragment dotyczący opcjonalnych parametrów.

Mike również rozmowy na temat stosowania wielu ograniczeń i mówi:

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

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

który również działa świetnie ... aż chce wiele ograniczeń i opcjonalny parametr.

Jak wiemy, zastosowanie ? pozwala na opcjonalny parametr.Więc biorąc powyższy przykład, można by przypuszczać, że

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

ogranicza parametr id być liczby całkowite większe niż 0, albo pusta (w tym przypadku stosowana jest domyślna 1). W rzeczywistości, pojawia się komunikat o błędzie:

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

Okazuje się, że Postanowienie ograniczeń sprawy! Po prostu wprowadzenie opcjonalnego ograniczenie ?po wszystkie inne ograniczenia daje zamierzone zachowanie

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

Działa to na więcej niż 2, a także ograniczeń, na przykład

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

Pomocna wskazówka na temat zamówienia. – Nicholi

Powiązane problemy