2010-04-12 11 views
20

Mam ten zestaw tras:Routing do działań o tych samych nazwach, ale innych parametrach

 routes.MapRoute(
      "IssueType", 
      "issue/{type}", 
      new { controller = "Issue", action = "Index" } 
     ); 

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

Oto klasa kontrolera:

public class IssueController : Controller 
{ 
    public ActionResult Index() 
    { 
     // todo: redirect to concrete type 
     return View(); 
    } 

    public ActionResult Index(string type) 
    { 
     return View(); 
    } 
} 

dlaczego, kiedy i poprosić http://host/issue ja dostać The current request for action 'Index' on controller type 'IssueController' is ambiguous between the following action methods:
Spodziewam się, że pierwsza metoda powinna działać, gdy nie ma żadnych parametrów, a druga po określonym parametrze.

gdzie popełniłem błąd?

UPD: możliwy duplikat: Can you overload controller methods in ASP.NET MVC?

UPD 2: ze względu na link powyżej - nie ma to jakikolwiek legalny sposób, aby działanie przeciążenia, prawda?

UPD 3: metody działania nie mogą być przeciążone na podstawie parametrów (c) http://msdn.microsoft.com/en-us/library/system.web.mvc.controller%28VS.100%29.aspx

Odpowiedz

10

chciałbym mieć jedną metodę Index, który wygląda na prawidłowy typ zmiennej

public class IssueController : Controller 
{ 
    public ActionResult Index(string type) 
    { 
     if(string.isNullOrEmpty(type)){ 
      return View("viewWithOutType");} 
     else{ 
      return View("viewWithType");} 
    } 
} 

EDIT:

Co powiesz na tworzenie niestandardowego atrybutu, który szuka określonej wartości żądania, tak jak w tym poście: StackOverflow

[RequireRequestValue("someInt")] 
public ActionResult MyMethod(int someInt) { /* ... */ } 

[RequireRequestValue("someString")] 
public ActionResult MyMethod(string someString) { /* ... */ } 

public class RequireRequestValueAttribute : ActionMethodSelectorAttribute { 
    public RequireRequestValueAttribute(string valueName) { 
     ValueName = valueName; 
    } 
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { 
     return (controllerContext.HttpContext.Request[ValueName] != null); 
    } 
    public string ValueName { get; private set; } 
} 
+0

Tak, to oczywiste, ale nie faktycznie rozwiązanie dla kwestia – zerkms

+1

Tak, to przynieść rodzaj przeciążenia, ale zbyt brudne, więc postanowiłem zmienić nazwę drugiej metody.dzięki – zerkms

1

Można to zrobić za pomocą ActionFilterAttribute, który sprawdza parametry za pomocą odbicia (próbowałem), ale jest to zły pomysł. Każda odmienna akcja powinna mieć własną nazwę.

Dlaczego nie nazwać dwóch metod "Indeks" i "Pojedynczy", powiedzmy, i żyć z ograniczeniem nazewnictwa?

W przeciwieństwie do metod, które są powiązane w czasie kompilacji na podstawie zgodnych sygnatur, brakująca wartość trasy na końcu jest traktowana jak pusta.

Jeśli chcesz, aby [hack] ActionFilterAttribute, który pasuje do parametrów, daj mi znać, a ja dodam do niego link, ale jak powiedziałem, jest to zły pomysł.

+0

Już zmieniam nazwę na drugą, więc mam 2 metody. I dostaję wiele linków do ActionFilterAttribute, faktycznie - to gorsze rozwiązanie. mimo wszystko dziekuję. – zerkms

1

Wszystko, co musisz zrobić, to oznacz swoją drugą akcję za pomocą [HttpPost]. Na przykład:

public class IssueController : Controller 
{ 
    public ActionResult Index() 
    { 
     // todo: redirect to concrete type 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Index(string type) 
    { 
     return View(); 
    } 
} 
+7

Kto ci powiedział, że drugi jest POSTED? – zerkms

+0

Wydaje mi się to bardzo dziwne ... –

+0

Widziałem to często, zwłaszcza w przypadku metod logowania - jeden Uzyskaj akcję, aby obsłużyć początkowy widok, i Opublikuj, aby zaakceptować żądanie logowania i przekierowanie. Generalnie widziałem również znacznik 'HttpGet' na pierwszej, nie wiem, które (jeśli w ogóle) wersji szkieletu tego wymagają, ale oznaczanie obydwu ułatwia zrozumienie. – brichins

5

Pobiegłem do podobnej sytuacji, gdzie chciałem moje „Indeks” działania do obsługi renderowania gdybym miał identyfikator określony lub nie. Rozwiązaniem, które znalazłem, było uczynienie parametru ID metodą indeksu opcjonalną. Na przykład, początkowo próbował posiadające obie:

public ViewResult Index() 
{ 
    //... 
} 
// AND 
public ViewResult Index(int entryId) 
{ 
    //... 
} 

a ja po prostu łączy je i zmienił je na:

public ViewResult Index(int entryId = 0) 
{ 
    //... 
} 
+0

To może być rozwiązanie dla .NET 4.0, ale używałem 3.5 tych dni ;-) – zerkms

Powiązane problemy