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

时间:2012-01-12 04:17:25

标签: c# asp.net-mvc-3 razor

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

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

9 个答案:

答案 0 :(得分:52)

我认为这应该可以解决问题:

// 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目前已关闭,因此我无法对其进行测试,但它应该按预期工作。

答案 1 :(得分:3)

为了扩展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"];

答案 2 :(得分:2)

要添加到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<RouteData>)previousValues["MS_DirectRouteMatches"];
    var routeValueDictionaryFromMsDirectRouteMatches = routeDataAsListFromMsDirectRouteMatches.FirstOrDefault();
    if (routeValueDictionaryFromMsDirectRouteMatches == null) return;
    previousActionName = routeValueDictionaryFromMsDirectRouteMatches.Values["action"].ToString();
    if (previousActionName == "") previousActionName = "Index";
}

答案 3 :(得分:1)

RouteData对象可以访问此信息:

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

答案 4 :(得分:1)

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

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

如果你想进行上一步行动

答案 5 :(得分:0)

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

答案 6 :(得分:0)

这是我通过引用来简化提取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;
    }

答案 7 :(得分:0)

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

var fullUrl = Request.UrlReferrer.ToString();
<a href="@fullUrl">Back</a>

答案 8 :(得分:0)

这是一种轻量级的方法,可以在不创建响应对象的情况下执行此操作。

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;
    }
}