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

C# 路由:当前操作请求[…]在以下操作方法之间不明确,c#,asp.net-mvc,C#,Asp.net Mvc,我有一个名为Browse.chtml的视图,用户可以在其中输入搜索词,或将搜索词留空。输入搜索词时,我想将页面指向http://localhost:62019/Gallery/Browse/{Searchterm}如果没有输入任何内容,我希望将浏览器指向http://localhost:62019/Gallery/Browse/Start/Here 当我尝试此操作时,会出现以下错误: 当前对控制器类型“GalleryController”的操作“浏览”请求在以下操作方法之间不明确: AutoAp

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

当我尝试此操作时,会出现以下错误:

当前对控制器类型“GalleryController”的操作“浏览”请求在以下操作方法之间不明确: AutoApp_Mvc.Controllers.GalleryController类型上的System.Web.Mvc.ActionResult浏览(System.String) AutoApp_Mvc.Controllers.GalleryController类型上的System.Web.Mvc.ActionResult浏览(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
         });

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

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

尽管您的两个浏览方法都是有效的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]
属性应用于一个来区分它。使用与上述相同的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);
}

我不知道问题是何时提出的。此解决方案可用,但您可以使用:

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

我认为需要指出的是,您不需要使用request类隐式地测试querystring参数

MVC为您进行映射(除非您对MVC路线进行了重大更改)

因此,actionlink路径

/umbraco/Surface/LoginSurface/Logout?DestinationUrl=/home/
将自动对(曲面)控制器可用,并定义以下参数:

public ActionResult Logout(string DestinationUrl)

MVC完成了这项工作。

在默认路由之前的RouteConfig.cs中添加以下代码

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

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

    }
[路线(“Cars/deteals/{id:int}”)]
public ContentResult deteals(int-id)
{
退货内容(“车号为“+ID+”);
}
[路线(“Cars/deteals/{name}”)]
public ContentResult deteals(字符串名称)
{
返回内容(“车名为“+name+”);
}

那么,我需要在上面的示例中创建一个新视图吗?看起来使用ActionName标记没有什么帮助,因为我认为这只能重命名所有的action方法(无法同时保留这两个方法)。很高兴知道MVC是如何工作的。谢谢。不,您不需要创建任何新视图。您仍然可以为两个操作重用相同的视图。只需将视图名称作为第一个参数传递给
返回视图(“浏览”,摘要)
在将来的版本中会包含重载吗?修改路由是额外的工作,在进行更改时需要额外的维护。@OldGeezer可能不会,因为有一个解决方法(如上所述),并且控制器中的重载操作方法通常不是一个好主意。
    [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>");

    }