重定向到操作,但 URL 上缺少参数操作

本文关键字:操作 参数 重定向 URL | 更新日期: 2023-09-27 17:55:17

我正在关注这篇文章 重定向到带有参数的操作来执行此操作

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

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

更新:路由配置.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 }
        );
    }

谢谢

重定向到操作,但 URL 上缺少参数操作

正在发生的事情是,您的默认路由定义为

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

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

在 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 加载索引。

有两种方法可以解决这个问题,从最简单的开始

解决方案 1:

在服务控制器上,不要将方法命名为Index,而是将其命名为其他任何名称,例如NotIndex,IDoStuff等。 这样做会导致重定向重定向到Service/IDoStuff(w/e)。 但是,执行此方法意味着本地主机/appname/服务将生成 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/机器配置等中。

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