asp.net mvc routing:如何使用默认动作但非默认参数?

时间:2011-04-08 06:59:16

标签: asp.net-mvc routing url-routing asp.net-mvc-routing

我正在改写这个问题,因为到目前为止的答案显示我没有把它定义得足够好。我将留下原始问题以供参考。

设置路由时,您可以为不同的网址/路由部分指定默认值。让我们考虑VS向导生成的示例:

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

在此示例中,如果未指定controller,将使用DefaultPageController,如果未指定action,则将使用“Index”操作。 网址通常如下:http://mysite/MyController/MyAction

如果Url中没有这样的操作:http://mysite/MyController那么将使用索引操作。

现在让我们假设我的控制器Index和AnotherAction中有两个动作。与其对应的网址分别为http://mysite/MyControllerhttp://mysite/MyController/AnotherAction。我的“索引”操作接受参数id。因此,如果我需要将参数传递给我的Index操作,我可以这样做:http://mysite/MyController/Index/123。请注意,与URL http://mysite/MyController不同,我必须明确指定Index操作。我想要做的是能够通过http://mysite/MyController/123而不是http://mysite/MyController/Index/123。我不需要此URL中的“索引”我希望mvc引擎识别,当我要求http://mysite/MyController/123时,123不是动作(因为我没有定义具有此名称的动作),但是参数到我的默认操作“索引”。如何设置路由以实现此目的?

以下是问题的原始措辞。


我有一个控制器,有两种方法,如此

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

    [HttpPost]
    public ActionResult Index(SomeFormData data)
    {
        return View();

    }

这使我可以在用户导航到此网址(GET)时以及随后发回表单(POST)时处理类似http://website/Page的网址。

现在,当我处理回发帖时,在某些情况下我想将浏览器重定向到此网址:

http://website/Page/123

其中123是某个整数,我需要一种方法来处理我的控制器中的这个URL。

如何设置路由,这有效吗?目前我有向导生成的“默认”路由,如下所示:

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

我尝试添加另一个这样的控制器方法:

public ActionResult Index(int id)
{
    return View();
}

但是这不起作用,因为抛出了模棱两可的动作异常:

  

当前的行动请求'指数'   在控制器类型'PageController'上   以下是不明确的   行动方式:   System.Web.Mvc.ActionResult Index()on   键入PageController   System.Web.Mvc.ActionResult   PageController类型的索引(Int32)

我必须补充一点,我在这个控制器中也有其他动作。如果我没有,This会有用。

4 个答案:

答案 0 :(得分:11)

以下是如何解决这个问题:

您可以创建一个路由约束,以向路由引擎指示,如果您在url中有某个看起来像数字的内容(123),那么这是默认操作的操作参数,如果您有某些内容不是看起来像一个数字(AnotherAction)然后它就是一个动作。

考虑以下代码:

routes.MapRoute(
  "MyController", "MyController/{productId}", 
  new {controller="My", action="Index"}, 
  new {productId = @"\d+" });

此路由定义仅匹配http://mysite/MyController/123中MyController之后的数值,因此不会干扰在同一控制器上调用另一个操作。

来源:Creating a Route Constraint

答案 1 :(得分:3)

如果保持变量名仍为ID,则无需更改任何内容。

将帖子1重命名为“PostIndex”并添加此属性:

[ActionName("Index")]

关于SO here的同样问题。

好的,如果有帮助的话,这里有一个剪切/粘贴答案。

public ActionResult Index()    {        
return View();    
}    
[AcceptVerbs(HttpVerbs.Post), ActionName("Index")]   
public ActionResult PostIndex(SomeFormData data)    {        
return View();    
}

答案 2 :(得分:2)

哦,我现在明白了。我认为使用默认路由是不可能的,您需要映射自定义路由。

    // /MyController/AnotherAction
    routes.MapRoute(
        null,
        "MyController/AnotherAction",
        new { controller = "DefaultPage", action = "AnotherAction" }
    );

    // /MyController
    // /MyController/id
    routes.MapRoute(
        null,
        "MyController/{id}",
        new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional }
    );

PS。默认路由 / / MyController / id 必须最后映射。

答案 3 :(得分:0)

我认为你想要返回相同的视图,但是你需要了解你正在做两件不同的事情。一个是接收帖子,另一个是通过get访问,另一个是通过get和参数访问...

你应该做3个不同名称的actionresult,并返回与View相同的视图(“ThisIsTheResult”)