【问题标题】:Drop Route Values on Redirect重定向时丢弃路由值
【发布时间】:2012-08-01 20:03:40
【问题描述】:

所以,我已经尝试了几个小时来解决理论上应该非常简单的问题。让我们来看看这个示例网址:

http://sample.com/products/in/texas/dallas

这会映射到特定的路线:

routes.MapRoute(
    "products",
    "products/in/{state}/{city}",
    new { controller = "Products", action = "List", state = UrlParameter.Optional, city = UrlParameter.Optional });

在我的操作方法中,我可以进行查找以确保“texas”和“dallas”存在,并且“dallas”存在于德克萨斯州。这一切都很好,花花公子。但是,在城市不存在的情况下(因为地理不正确或拼写错误),我希望它备份州级。示例:

http://sample.com/products/in/texas/dallax

这应该发出重定向到

http://sample.com/products/in/texas

执行此操作的“简单”方法是简单地发出重定向调用,如下所示:

return Redirect("/products/in/" + stateName);

但是,我试图将其与 URL 结构分离;例如,如果我们决定更改路由的外观(例如,将模式更改为products/around/{state}/{city}),那么我必须知道我需要更新此控制器以修复 URL 重定向。

如果我可以制定一个解决方案,只检查路由值并找出问题所在,那么我不必担心更改路由模式,因为仍然可以找出路由值。

理想情况下,我希望做这样的事情:

return RedirectToRoute(new { controller = "Products", action = "List", state = state });

(注意,这是一个简化的示例;控制器名称和操作方法名称等“必需”路由片段将分别由通用参数和表达式检查确定)。

这实际上执行了重定向,但是,来自当前请求的路由值被附加到重定向上,因此您进入重定向循环(请注意,我没有包括城市路由值在路由对象中)。 如何阻止“城市”路线值包含在此重定向中?

我尝试了以下方法来摆脱路由值:

  1. 编写我自己的RouteValueDictionary / 匿名路由数据对象并将其传递给RedirectToRoute 的重载。
  2. 创建我自己的操作结果来检查RouteTable.Routes并自己找到路线,并自己更换令牌。这似乎是最“笨拙”的,并且似乎是在重新发明轮子。
  3. 创建一个像RedirectWithout 这样的方法,它接受一个键值并调用RedirectToRouteResult.RouteValues.Remove(key) - 这也不起作用。
  4. 我还尝试为我不想添加的键添加空值;但是,这会改变到不正确的路径 - 即 new { controller = "Products", action = "List", state = stateName, city = (string)null } 发出重定向到 /Products/List?state=Texas 这不是正确的 URL。

这一切似乎都源于 RedirectToRoute 采用当前请求上下文来构造虚拟路径数据。有解决办法吗?

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-routing


    【解决方案1】:

    如果您使用的是 T4MVC,您应该能够执行以下操作:

    return RedirectToAction(MVC.Products.List(state, null));
    

    你试过了吗?

    return RedirectToRoute(new 
    {
        controller = "Products", 
        action = "List", 
        state = state,
        city = null, 
    });
    

    回复 cmets

    也许 MVC 很困惑,因为您的可选参数不在末尾。下面应该与上面指定city = nullRedirectToRoute一起使用:

    routes.MapRoute(
        "products",
        "products/in/{state}/{city}",
        new
        {
            controller = "Products",
            action = "List",
            // state = UrlParameter.Optional, // only let the last parameter be optional
            city = UrlParameter.Optional 
        });
    

    然后您可以添加另一个路由来处理 URL,其中 state 是可选的:

    routes.MapRoute(null, // I never name my routes
        "products/in/{state}",
        new
        {
            controller = "Products",
            action = "List",
            state = UrlParameter.Optional 
        });
    

    【讨论】:

    • 确实,我尝试过将路由值设为 null(例如,city = (string)null。这会导致没有参数的有效重定向,但 URL 不正确。
    • 如果它没有重定向到/products/in/texas,它会重定向到哪个URL?
    • 另外,尽管我对它的用法有争论,但我在 T4MVC 上被否决了。 =/
    • /products/list?state=Texas。现在我想这可能是因为我没有指定我在 MapRoute 中使用的路由名称,所以当我执行 RedirectToRoute(RouteNames.Product, new { blah }) 时,它会抛出一个异常,它找不到与提供的值匹配的路由。
    • 另一条路线可能最终成为我前进的方向,这变得多么令人沮丧=/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2011-08-19
    • 2021-05-28
    • 2018-05-24
    • 1970-01-01
    相关资源
    最近更新 更多