路由:当前的操作请求[...]在以下操作方法之间不明确

时间:2012-05-19 19:12:51

标签: c# asp.net-mvc

我有一个名为Browse.chtml的视图,用户可以在其中输入搜索字词,或将搜索字词留空。输入搜索字词时,我想将网页定向到http://localhost:62019/Gallery/Browse/{Searchterm},当没有输入任何内容时,我想将浏览器定向到http://localhost:62019/Gallery/Browse/Start/Here

当我尝试这个时,我收到错误:

  

当前的控制器类型“GalleryController”上的“浏览”操作请求在以下操作方法之间不明确:   System.Web.Mvc.ActionResult在AutoApp_MVC.Controllers.GalleryController类型上浏览(System.String)   System.Web.Mvc.ActionResult在AutoApp_MVC.Controllers.GalleryController类型上浏览(Int32,System.String)

我在MVC所做的一切都是第一次。我不知道还有什么可以尝试。

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

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

4 个答案:

答案 0 :(得分:152)

控制器上最多只能有2个具有相同名称的操作方法,为此,1必须为[HttpPost],另一个必须为[HttpGet]

由于您的两个方法都是GET,因此您应该重命名其中一个操作方法或将其移动到另一个控制器。

虽然您的2个Browse方法是有效的C#重载,但MVC操作方法选择器无法确定要调用的方法。它将尝试匹配方法的路由(反之亦然),并且此算法不是强类型的。

您可以使用指向不同操作方法的自定义路线来完成您想要的操作:

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

......并且在控制器......

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

您也可以通过将[ActionName]属性应用于其中来keep the action methods named the same in the controller来区分它。使用与上面相同的Global.asax,您的控制器将如下所示:

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

答案 1 :(得分:4)

我不知道问题何时被问到这个解决方案是否可用,但您可以使用:

Request.QueryString["key"]

所以这应该可以解决你的问题:

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

答案 2 :(得分:1)

我认为要点是你不需要使用请求类隐式测试查询字符串参数。

MVC为您进行映射(除非您对MVC路由进行了严格更改)。

因此是

的actionlink路径
/umbraco/Surface/LoginSurface/Logout?DestinationUrl=/home/
使用定义的参数

将自动为您的(表面)控制器提供

public ActionResult Logout(string DestinationUrl)

MVC完成这项工作。

答案 3 :(得分:1)

默认路由

之前在RouteConfig.cs中添加以下代码
routes.MapMvcAttributeRoutes();

并在控制器中添加路由属性,例如:

    [Route("Cars/deteals/{id:int}")]
    public ContentResult deteals(int id)
    {
        return Content("<b>Cars ID Is " + id + "</b>");
    }

    [Route("Cars/deteals/{name}")]
    public  ContentResult deteals(string name)
    {
        return Content("<b>Car name Is " + name + "</b>");

    }