【发布时间】: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