RedirectToAction,其中包含对URL的参数缺失操作

时间:2015-06-11 00:39:28

标签: c# asp.net-mvc

我正在关注此帖子RedirectToAction with parameter来执行此操作

return RedirectToAction("index","service",new {groupid = service.GroupID});

由于某种原因,它返回的URL不是预期的。例如,它返回http://localhost/appname/service/index?groupid=5而不是http://localhost/appname/service?groupid=5。有没有办法让它返回预期的URL?

更新:RouteConfig.cs

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

由于

2 个答案:

答案 0 :(得分:2)

正在发生的是您的默认路由被定义为

url: "{controller}/{action}/{id}",

Index()方法没有名为id的参数(其groupId),因此路由引擎只使用{action}的默认值。您可以通过将参数名称更改为id

来生成所需的路径
public ActionResult Index(int id)

并在另一种方法中使用

RedirectToAction("Index","Service",new {id = service.GroupID})

或在默认路线

之前添加新的路线定义
routes.MapRoute(
  name: "Service",
  url: "Service/Index/{groupId}",
  defaults: new { controller = "Service", action = "Index", groupId = UrlParameter.Optional }
);

请注意,在这两种情况下,这都会产生../Service/Index/5而不是../Service/Index?groupId=5,但这通常会被认为更好(如果您真的想要第二个选项,那么请将上面的路线更改为url: "Service/Index", (省略最后一个参数)

答案 1 :(得分:1)

好的,我想出来并在测试环境中重现它。这是因为路由。

在MVC中,当您使用泛型捕获所有路径时,就像您在此处所做的那样:

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );

它总是将index视为映射到控制器根目录的默认操作。因此localhost / somecontroller将始终调用index,并且url将在localhost / somecontroller或localhost / somecontroller / index中加载索引。

从最简单的

开始,有两种方法可以解决这个问题

解决方案1:

在服务控制器上,不要将您的方法命名为Index,将其命名为其他内容,如NotIndex,IDoStuff等等。只是这样做会导致重定向重定向到Service / IDoStuff(w / e)。但是,执行此方法意味着localhost / appname / service将生成404(作为默认操作"索引"不存在)。

解决方案2:允许您保留名为Index

的操作
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute(
            name: "Home",
            url: "Home/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
        routes.MapRoute(
            name: "Service",
            url: "Service/Index/{id}",
            defaults: new { controller = "Service", action = "Index", id = UrlParameter.Optional }
        );

解决方案2问题 指定这样的严格路由会打破你的默认路由catch all,如果你把默认的catch all路由回到原来的问题,因为MVC会经历路由集合并将每个路由应用到url,直到找到一个匹配,匹配的第一个是它使用的那个,如果它找不到匹配的路由,那么bam 404(找不到页面/没有资源)。

然而,像你一样,我想要严格的网址,而不是默认网址,所以我所做的就是解决方案2。

然后返回我的根网址加载主页 - >索引我在web.config中添加了重写规则

<system.webServer>
  <rewrite>
    <rules>
      <rule name="RootRedirect" stopProcessing="true">
        <match url="^$" />
        <action type="Redirect" url="/Home/Index/{R:0}" />
      </rule>
    </rules>
  </rewrite>    
</system.webServer>

为此,您需要在IIS(已安装)中启用UrlRewrite功能,以便它存在于gac / machine配置等中。

此外,重新路由规则似乎是一个永久重定向规则,因此一旦客户端浏览器访问过该站点一次,浏览器将重定向到该服务器而不向服务器发出2个请求。