2012-05-19 15 views
69

Mam widok o nazwie Browse.chtml, w którym użytkownik może wpisać szukany termin lub pozostawić puste pole wyszukiwania. Podczas wpisywania wyszukiwanego hasła chcę skierować stronę na adres http://localhost:62019/Gallery/Browse/{Searchterm}, a gdy nic nie zostanie wprowadzone, chcę skierować przeglądarkę na stronę http://localhost:62019/Gallery/Browse/Start/Here.Routing: bieżące żądanie działania [...] jest niejednoznaczne między następującymi metodami działania

Kiedy próbuję to pojawia się błąd:

The current request for action 'Browse' on controller type 'GalleryController' is ambiguous between the following action methods: System.Web.Mvc.ActionResult Browse(System.String) on type AutoApp_MVC.Controllers.GalleryController System.Web.Mvc.ActionResult Browse(Int32, System.String) on type AutoApp_MVC.Controllers.GalleryController

Wszystko robię z MVC jest po raz pierwszy. Nie jestem pewien, co jeszcze można spróbować w tym momencie.

public ActionResult Browse(string id) 
{ 
    var summaries = /* search using id as search term */ 
    return View(summaries); 
} 

public ActionResult Browse(string name1, string name2) 
{ 
    var summaries = /* default list when nothing entered */ 
    return View(summaries); 
} 

Mam również ten w Global.asax.cs:

routes.MapRoute(
     "StartBrowse", 
     "Gallery/Browse/{s1}/{s2}", 
     new 
     { 
      controller = "Gallery", 
      action = "Browse", 
      s1 = UrlParameter.Optional, 
      s2 = UrlParameter.Optional 
     }); 



    routes.MapRoute(
     "ActualBrowse", 
     "Gallery/Browse/{searchterm}", 
     new 
     { 
      controller = "Gallery", 
      action = "Browse", 
      searchterm=UrlParameter.Optional 
     }); 

Odpowiedz

119

Można mieć tylko maksymalnie 2 metod działania o tej samej nazwie na kontrolerze, a w tym celu, 1 musi być [HttpPost], a drugi musi być [HttpGet].

Ponieważ obie metody są GET, powinieneś zmienić nazwę jednej z metod akcji lub przenieść ją do innego kontrolera.

Mimo że twoje 2 metody przeglądania są poprawnymi przeciążeniami C#, selektor metody działania MVC nie może ustalić, którą metodę wywołać. Spróbuje dopasować trasę do metody (lub odwrotnie), a ten algorytm nie jest mocno napisany.

Można osiągnąć to, czego chcą przy użyciu niestandardowych trasach, wskazując na różne sposoby działania:

... w Global.asax

routes.MapRoute(// this route must be declared first, before the one below it 
    "StartBrowse", 
    "Gallery/Browse/Start/Here", 
    new 
    { 
     controller = "Gallery", 
     action = "StartBrowse", 
    }); 

routes.MapRoute(
    "ActualBrowse", 
    "Gallery/Browse/{searchterm}", 
    new 
    { 
     controller = "Gallery", 
     action = "Browse", 
     searchterm = UrlParameter.Optional 
    }); 

... iw sterowniku ...

public ActionResult Browse(string id) 
{ 
    var summaries = /* search using id as search term */ 
    return View(summaries); 
} 

public ActionResult StartBrowse() 
{ 
    var summaries = /* default list when nothing entered */ 
    return View(summaries); 
} 

Możesz również być w stanie keep the action methods named the same in the controller, stosując atrybut [ActionName], aby go rozróżnić. Stosując tę ​​samą Global.asax jak wyżej, kontroler będzie wtedy wyglądać tak:

public ActionResult Browse(string id) 
{ 
    var summaries = /* search using id as search term */ 
    return View(summaries); 
} 

[ActionName("StartBrowse")] 
public ActionResult Browse() 
{ 
    var summaries = /* default list when nothing entered */ 
    return View(summaries); 
} 
+0

Czy muszę zatem utworzyć nowy widok w powyższym przykładzie? Wygląda na to, że nie pomaga użycie znacznika ActionName, ponieważ myślę, że działa tylko po to, aby zmienić nazwy wszystkich metod działania (nie można ich zachować jednocześnie). Dobrze wiedzieć, jak działa MVC. Dzięki. – Dave

+5

Nie, nie trzeba tworzyć nowych widoków. Nadal możesz użyć tego samego widoku dla obu działań. Wystarczy przekazać nazwę widoku jako pierwszy argument do 'return View (" Browse ", podsumowania);' – danludwig

+0

Świetnie, dziękuję. – Dave

3

nie wiem kiedy pytano rozwiązanie to było dostępne, ale można użyć:

Request.QueryString["key"] 

tak to powinno działać dobrze dla swojego problemu:

[HttpGet] 
public ActionResult Browse() 
{ 
    if(Request.QueryString["id"] != null)   
     var summaries = /* search using id as search term */ 
    else /*assuming you don't have any more option*/ 
     var summaries = /* default list when nothing entered */ 

    return View(summaries); 
} 
1

myślę, że punkt odniesienia jest to, że nie trzeba w sposób dorozumiany testowania parametrów kwerendy przy użyciu klasy żądania.

MVC wykonuje dla ciebie mapowanie (chyba że wprowadziłeś poważne zmiany na swoich trasach MVC).

Zatem actionlink ścieżka

/umbraco/Surface/LoginSurface/Logout?DestinationUrl=/home/ 

automatycznie będzie dostępny do kontrolera (powierzchni) z określonym parametrem:

public ActionResult Logout(string DestinationUrl) 

MVC działa.

Powiązane problemy