Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重定向到具有不同参数值的同一路由_C#_Asp.net Mvc_Routes - Fatal编程技术网

C# 重定向到具有不同参数值的同一路由

C# 重定向到具有不同参数值的同一路由,c#,asp.net-mvc,routes,C#,Asp.net Mvc,Routes,我的情况是,我正在一个博客网站上工作,该网站的URL形式如下: /blog/{id}/{title slug} {title slug}纯粹是一个用户友好的字符串,旨在使url看起来更漂亮。仅id就足以唯一地决定一切 我在一个全局ActionFilterAttribute中有一些代码,可以识别出{title slug}丢失(或不正确),然后它就会这样做 filterContext.Result = new RedirectResult(url.Action(action, controller,

我的情况是,我正在一个博客网站上工作,该网站的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                
);
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));
}
routeData["slug"] = routeData["slug"].ToString().Replace("-", "_");
如果slug错误,我要重定向的代码(简化形式)如下所示:

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                
);
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));
}
routeData["slug"] = routeData["slug"].ToString().Replace("-", "_");
如您所见,我可以从当前路由数据中获取操作和控制器,并使用修改后的路由数据创建一个新的routeValueDictionary。我遇到的问题是,它拾取了第一条路线的url(称为“ShowFeedAndFollow”),而不是我真正想要的那个,它以“ShowFeed”的形式出现

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

我可能只需要重新排列路线,使我想要的是第一条。然而,这显然是一个脆弱的解决方案,如果我决定做一些改变这些事情顺序的事情,它就会崩溃


因此,我的问题是:假设我在一个过滤器属性中,并且拥有使我来到这里的路由的所有数据,我只想重定向到完全相同的路由/url,但有一个参数发生了更改,如何才能最好地做到这一点?

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

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

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

var routeData = filterContext.RouteData.Values;
然后对参数进行如下所需的任何更改:

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                
);
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));
}
routeData["slug"] = routeData["slug"].ToString().Replace("-", "_");
最后使用RedirectToRouteResult代替RedirectResult

filterContext.Result = new RedirectToRouteResult(routeData);

可能是的。但这大概仍然会引导我走上硬编码的道路,而我本不希望这样做。正如我所提到的(在那堵文本墙的某个地方),同样的逻辑正在被用于一些事情,我也有一些旧的路由,它们现在已经过时了,除了实际的url(即我们过去使用
/bongoblog/{shortcode}/{slug}
,对于有旧书签的人来说,路由仍然存在)。我希望有更优雅的东西,因为我有路由对象和路由字典,而不需要很多检查。。。