【问题标题】:Redirect to same route with different parameter values重定向到具有不同参数值的同一路由
【发布时间】:2015-01-25 04:16:10
【问题描述】:

我在一个博客网站上工作,该网站的 URL 格式如下:

/blog/{id}/{title-slug}

{title-slug} 纯粹是一个用户友好的字符串,旨在使 url 看起来更漂亮。仅 id 就足以唯一确定一切。

我在全局 ActionFilterAttribute 中有一些代码可以识别 {title-slug} 丢失(或不正确),然后它会这样做

filterContext.Result = new RedirectResult(url.Action(action, controller, routeValueDictionary));

除了一个问题外,这几乎可以正常工作。我有多个路由匹配控制器和动作,它似乎只选择第一个......

让我们看一些代码。我的相关路线如下所示:

routes.MapRoute
(
    "ShowFeedAndFollow",
    "blog/{shortcode}/{slug}/followme",
    new { controller = "Public", action = "ShowFeed", shortcode = "", slug = "", followme = true } // Parameter defaults                
);

routes.MapRoute
(
    "ShowFeed",
    "blog/{shortcode}/{slug}",
    new { controller = "Public", action = "ShowFeed", shortcode = "", slug = "" } // Parameter defaults                
);

如果 slug 错误,我的重定向代码如下所示(简化形式):

var slug = filterContext.RouteData.Values["slug"] == null ? "" : filterContext.RouteData.Values["slug"].ToString();
var action = filterContext.RouteData.Values["action"] == null ? "" : filterContext.RouteData.Values["action"].ToString();
var controller = filterContext.RouteData.Values["controller"] == null ? "" : filterContext.RouteData.Values["controller"].ToString();
RouteValueDictionary routeValueDictionary = new RouteValueDictionary(filterContext.RouteData.DataTokens);
var canonicalSlug = GetCanonnicalSlug();
routeValueDictionary["slug"] = canonicalSlug;

if (!String.IsNullOrEmpty(canonicalSlug) && !slug.Equals(canonicalSlug))    
{
    var url = new UrlHelper(filterContext.RequestContext);
    filterContext.Result = new RedirectResult(url.Action(action, controller, routeValueDictionary));
}

如您所见,我可以从当前路由数据中获取操作和控制器,并使用修改后的路由数据创建一个新的 routeValueDictionary。我遇到的问题是它获取了第一条路线的网址(称为“ShowFeedAndFollow”),而不是我真正想要的网址,它以“ShowFeed”的形式出现。

我无法对路由名称进行硬编码(因为相同的代码目前适用于博客和博客中的帖子)。我有路由对象 (filterContext.RouteData.Route),但我似乎找不到在给定该对象的情况下生成 url 的方法。

我可能只是重新排序路线,以便我想要的路线是第一个。然而,如果我决定做一些改变这些事情的顺序的事情,这显然是一个脆弱的解决方案。

所以我总结的问题是这样的:假设我在一个过滤器属性中,并且拥有关于让我来到这里的路线的所有数据,我只想重定向到完全相同的路线/url,但改变了一个参数,我怎样才能最好地做到这一点?

【问题讨论】:

  • 可能,是的。但这大概仍然只是让我走上了我希望不必做的硬编码之路。正如我所提到的(在文本墙的某处),同样的逻辑被用于几件事,而且我也有旧的路由现在已经过时并且除了实际的 url 之外是相同的(即我们曾经使用/bongoblog/{shortcode}/{slug}对于旧书签的人来说,该路线仍然存在)。我希望有一些更优雅的东西,因为我有路由对象和路由字典而不需要大量检查......

标签: c# asp.net-mvc routes


【解决方案1】:

要使用 filterContext 中的参数进行路由,最好使用 RedirectToRouteResult 而不是 RedirectResult

你可以这样做:

首先收集所有路由数据,包括Controller Name、Action Name等参数。

var routeData = filterContext.RouteData.Values;

然后在参数中进行任何需要的更改,如下所示:

routeData["slug"] = routeData["slug"].ToString().Replace("-", "_");

最后使用 RedirectToRouteResult 代替 RedirectResult

filterContext.Result = new RedirectToRouteResult(routeData);

【讨论】:

    猜你喜欢
    • 2015-03-19
    • 1970-01-01
    • 2019-10-26
    • 2018-01-07
    • 2016-09-21
    • 2017-10-10
    • 2018-11-04
    • 1970-01-01
    • 2023-02-03
    相关资源
    最近更新 更多