如何从Referrer Uri获取Controller和Action名称?

从控制器和动作名称构建Uris有很多信息,但是我怎么能这样做呢?

基本上,我想要实现的是从引用页面获取Controller和Action名称(即Request.UrlReferrer)。 有没有一种简单的方法来实现这一目标?

我认为这应该做的伎俩:

// Split the url to url + query string var fullUrl = Request.UrlReferrer.ToString(); var questionMarkIndex = fullUrl.IndexOf('?'); string queryString = null; string url = fullUrl; if (questionMarkIndex != -1) // There is a QueryString { url = fullUrl.Substring(0, questionMarkIndex); queryString = fullUrl.Substring(questionMarkIndex + 1); } // Arranges var request = new HttpRequest(null, url, queryString); var response = new HttpResponse(new StringWriter()); var httpContext = new HttpContext(request, response) var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext)); // Extract the data var values = routeData.Values; var controllerName = values["controller"]; var actionName = values["action"]; var areaName = values["area"]; 

我的Visual Studio目前已关闭,所以我无法测试它,但它应该按预期工作。

为了扩展gdoron的答案, Uri类有一些方法可以抓取URL的左右部分而无需进行字符串解析:

 url = Request.UrlReferrer.GetLeftPart(UriPartial.Path); querystring = Request.UrlReferrer.Query.Length > 0 ? uri.Query.Substring(1) : string.Empty; // Arranges var request = new HttpRequest(null, url, queryString); var response = new HttpResponse(new StringWriter()); var httpContext = new HttpContext(request, response) var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext)); // Extract the data var values = routeData.Values; var controllerName = values["controller"]; var actionName = values["action"]; var areaName = values["area"]; 

RouteData对象可以访问此信息:

  var controller = RouteData.Values["controller"].ToString(); var action = RouteData.Values["action"].ToString(); 

要添加到gdoran接受的答案,我发现如果使用自定义路由属性,则不会填充操作。 以下为我工作:

 public static void SetUpReferrerRouteVariables(HttpRequestBase httpRequestBase, ref string previousAreaName, ref string previousControllerName, ref string previousActionName) { // No referrer found, perhaps page accessed directly, just return. if (httpRequestBase.UrlReferrer == null) return; // Split the url to url + QueryString. var fullUrl = httpRequestBase.UrlReferrer.ToString(); var questionMarkIndex = fullUrl.IndexOf('?'); string queryString = null; var url = fullUrl; if (questionMarkIndex != -1) // There is a QueryString { url = fullUrl.Substring(0, questionMarkIndex); queryString = fullUrl.Substring(questionMarkIndex + 1); } // Arrange. var request = new HttpRequest(null, url, queryString); var response = new HttpResponse(new StringWriter()); var httpContext = new HttpContext(request, response); var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext)); if (routeData == null) throw new AuthenticationRedirectToReferrerDataNotFoundException(); // Extract the data. var previousValues = routeData.Values; previousAreaName = previousValues["area"] == null ? string.Empty : previousValues["area"].ToString(); previousControllerName = previousValues["controller"] == null ? string.Empty : previousValues["controller"].ToString(); previousActionName = previousValues["action"] == null ? string.Empty : previousValues["action"].ToString(); if (previousActionName != string.Empty) return; var routeDataAsListFromMsDirectRouteMatches = (List)previousValues["MS_DirectRouteMatches"]; var routeValueDictionaryFromMsDirectRouteMatches = routeDataAsListFromMsDirectRouteMatches.FirstOrDefault(); if (routeValueDictionaryFromMsDirectRouteMatches == null) return; previousActionName = routeValueDictionaryFromMsDirectRouteMatches.Values["action"].ToString(); if (previousActionName == "") previousActionName = "Index"; } 

@gordon的解决方案有效,但您需要使用

  return RedirectToAction(actionName.ToString(), controllerName.ToString(),values); 

如果你想要采取以前的行动

我不相信有任何内置的方法来检索以前的Controller / Action方法调用。 您可以随时做的是包装控制器和操作方法,以便将它们记录在持久数据存储中,然后当您需要最后一个Controller / Action方法时,只需从数据库中检索它(或者您选择的任何方式)。

这是我从引用来简化提取url的方法,因为我在我的URL中有令牌(用“)”/“),所以你可以从中轻松提取控制器和动作:

 private static string GetURLSimplified(string url) { string separator = "))/"; string callerURL = ""; if (url.Length > 3) { int index = url.IndexOf(separator); callerURL = url.Substring(index + separator.Length); } return callerURL; } 

为什么需要从url构造ActionLink? ActionLink的目的与从某些数据创建URL相反。 所以在你的页面中只需:

 var fullUrl = Request.UrlReferrer.ToString(); Back 

这是一种轻量级方法,无需创建响应对象即可完成此操作。

 var values = RouteDataContext.RouteValuesFromUri(Request.UrlReferrer); var controllerName = values["controller"]; var actionName = values["action"]; 

使用此自定义HttpContextBase

 public class RouteDataContext : HttpContextBase { public override HttpRequestBase Request { get; } private RouteDataContext(Uri uri) { var url = uri.GetLeftPart(UriPartial.Path); var qs = uri.GetComponents(UriComponents.Query,UriFormat.UriEscaped); Request = new HttpRequestWrapper(new HttpRequest(null,url,qs)); } public static RouteValueDictionary RouteValuesFromUri(Uri uri) { return RouteTable.Routes.GetRouteData(new RouteDataContext(uri)).Values; } }