使用不同的参数值重定向到相同的路由

时间:2014-11-26 17:56:20

标签: c# asp.net-mvc routes

我有一种情况,我正在一个博客网站上工作,其网址为:

/博客/ {ID} / {标题段塞}

{title-slug}纯粹是一个用户友好的字符串,旨在使网址看起来更好。只有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。我遇到的问题是,它为第一条路线(称为&#34; ShowFeedAndFollow&#34;)而不是我真正想要的那条路线,以及#34; ShowFeed&#34;。< / p>

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

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

所以我总结的问题是这样的:鉴于我在一个过滤器属性中并且拥有关于路径的所有数据,这些数据让我在这里,我想重新定向到完全相同的路由/网址但是更改了一个参数,我怎么能最好地做到这一点?

1 个答案:

答案 0 :(得分:0)

要使用 filterContext 中的参数进行路由,最好使用 RedirectToRouteResult 代替 RedirectResult

您可以简单地执行以下操作:

首先收集所有路由数据,包括控制器名称,操作名称和其他参数。

var routeData = filterContext.RouteData.Values;

然后对像这样的参数进行所需的任何更改:

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

,最后使用 RedirectToRouteResult 代替 RedirectResult

filterContext.Result = new RedirectToRouteResult(routeData);