【问题标题】:RedirectToAction with parameter missing action on the URL在 URL 上带有参数缺失操作的 RedirectToAction
【发布时间】:2015-08-26 11:50:52
【问题描述】:

我正在关注这个帖子 RedirectToAction with parameter 来做这个

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

由于某种原因,它返回的 URL 不是预期的。例如,它返回 http://localhost/appname/service?groupid=5,而不是 http://localhost/appname/service/index?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 }
        );
    }

谢谢

【问题讨论】:

  • 显示来自RouteConfig.cs的路线
  • 我无法重现您的问题(对我来说很好)。尽管我建议您将ServiceController 中的Index() 方法的参数更改为int id 而不是int groupid 并使用return RedirectToAction("index","service",new {id = service.GroupID});,因此它会生成../Service/Index/5 而不是../Service/Index?groupid=5(或使用` url: "服务/索引/{groupid}",
  • @Ryios:GroupID 是整数类型。
  • @Stephen:将 groupid 更改为 id 后。有用。谢谢

标签: c# asp.net-mvc


【解决方案1】:

发生的事情是您的默认路由被定义为

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",(省略最后一个参数)

【讨论】:

    【解决方案2】:

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

    在 MVC 中,当您像这里一样使用通用的 catch all 路由时:

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

    它将始终将索引视为映射到控制器根目录的默认操作。所以 localhost/somecontroller 会一直调用 index,url 会在 localhost/somecontroller 或者 localhost/somecontroller/index 加载 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 问题 像这样指定严格的路由会破坏您的默认路由全部捕获,如果您将默认的全部捕获路由带回您的原始问题,因为 MVC 将遍历路由集合并将每个路由应用于 url,直到找到一个匹配的,第一个匹配的就是它使用的那个,如果它没有找到匹配的路由,那么 bam 404 (Page not found/no resource)。

    但是,像你一样,我想要严格的 url,而不是默认的,所以我所做的是我使用了解决方案 2。

    然后为了取回我的根 url 加载主页 -> 索引我在我的 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 次请求。

    【讨论】:

    • @Stephen Muecke 有更多关于 id != groupid 部分的信息,我认为这两个答案在技术上都是正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 2010-11-18
    • 2012-10-22
    • 2013-05-09
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    相关资源
    最近更新 更多