2012-05-19 10 views
69

Tengo una vista llamada Browse.chtml, donde el usuario puede ingresar un término de búsqueda o dejar el término de búsqueda en blanco. Al ingresar el término de búsqueda, deseo dirigir la página al http://localhost:62019/Gallery/Browse/{Searchterm} y cuando no se ingresa nada, deseo dirigir el navegador al http://localhost:62019/Gallery/Browse/Start/Here.Enrutamiento: la solicitud actual de [...] acción es ambigua entre los siguientes métodos de acción

Cuando intento esto, me sale el error:

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

Todo lo que estoy haciendo con MVC es por primera vez. No estoy seguro de qué más probar en este momento.

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

también tengo esto en 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 
     }); 

Respuesta

119

que sólo puede tener un máximo de 2 métodos de acción con el mismo nombre en un controlador, y con el fin de hacer eso, 1 debe ser [HttpPost], y el otro debe ser [HttpGet].

Dado que sus dos métodos son GET, debe cambiar el nombre de uno de los métodos de acción o moverlo a un controlador diferente.

Aunque sus 2 métodos de búsqueda son sobrecargas de C# válidas, el selector de método de acción MVC no puede determinar qué método invocar. Intentará hacer coincidir una ruta con el método (o viceversa), y este algoritmo no está fuertemente tipado.

Puede lograr lo que desee mediante rutas personalizadas que apuntan a diferentes métodos de acción:

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

... y en el controlador ...

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

También puede keep the action methods named the same in the controller, aplicando un atributo [ActionName] a uno para distinguirlo. Utilizando el mismo Global.asax que el anterior, el controlador sería parecido a esto:

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

Entonces, ¿tendré que crear una nueva vista en su ejemplo anterior? Parece que no ayuda usar la etiqueta ActionName, ya que creo que solo funciona para cambiar el nombre de todos los métodos de acción (no se pueden mantener ambos al mismo tiempo). Es bueno saber cómo funciona MVC. Gracias. – Dave

+5

No, no necesita crear ninguna vista nueva. Todavía puede reutilizar la misma vista para ambas acciones. Simplemente pase el nombre de la vista como el primer argumento para 'devolver vista (" Buscar ", resúmenes);' – danludwig

+0

Genial, gracias. – Dave

3

no sé cuando se hizo la pregunta esta solución estaba disponible pero se puede utilizar:

Request.QueryString["key"] 

Así que esto debería funcionar bien para su problema:

[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

Creo que el punto de ser hecho es que no es necesario para poner a prueba de forma implícita para los parámetros de cadena de consulta utilizando la clase de petición.

MVC realiza la asignación por usted (a menos que haya realizado cambios graves en sus rutas MVC).

Así, un camino ActionLink de

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

sería automáticamente a disposición de su controlador (superficie) con el parámetro definido:

public ActionResult Logout(string DestinationUrl) 

MVC hace el trabajo.

Cuestiones relacionadas