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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8830052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 04:41:30  来源:igfitidea点击:

How do I get the Controller and Action names from the Referrer Uri?

c#asp.net-mvc-3razor

提问by death_au

There's a lot of information for building Uris from Controller and Action names, but how can I do this the other way around?

从 Controller 和 Action 名称构建 Uris 有很多信息,但我怎么能反过来呢?

Basically, all I'm trying to achieve is to get the Controller and Action names from the referring page (i.e. Request.UrlReferrer). Is there an easy way to achieve this?

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

采纳答案by gdoron is supporting Monica

I think this should do the trick:

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

// 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"];

My Visual Studio is currently down so I could not test it, but it should work as expected.

我的 Visual Studio 目前已关闭,因此我无法对其进行测试,但它应该可以按预期工作。

回答by Judo

The RouteData object can access this info:

RouteData 对象可以访问此信息:

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

回答by Judo

I don't believe there is any built-in way to retrieve the previous Controller/Action method call. What you could always do is wrap the controllers and action methods so that they are recorded in a persistent data store, and then when you require the last Controller/Action method, just retrieve it from the database (or whatever you so choose).

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

回答by clement

This is a method I made to extract url simplified from referrer because I had token (finished with "))/") in my URL so you can extract easily controller and action from this:

这是我从引用中提取简化 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;
    }

回答by user2555515

Why would you need to construct ActionLink from a url ? The purpose of ActionLink is just the opposite to make a url from some data. So in your page just do:

为什么需要从 url 构造 ActionLink ?ActionLink 的目的与从一些数据制作 url 的目的相反。因此,在您的页面中只需执行以下操作:

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

回答by Marc

To add to gdoran's accepted answer, I found that the action doesn't get populated if a custom route attribute is used. The following works for me:

要添加到 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";
}

回答by DiSaSteR

@gordon's solution works, but you need to use

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

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

if you want to go to previous action

如果你想转到上一个动作

回答by Joe the Coder

To expand on gdoron's answer, the Uriclass has methods for grabbing the left and right parts of the URL without having to do string parsing:

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

回答by Carter Medlin

Here is a lightweight way to do this without creating response objects.

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

var values = RouteDataContext.RouteValuesFromUri(Request.UrlReferrer);

var controllerName = values["controller"];
var actionName = values["action"];

Uses this custom HttpContextBaseclass

使用这个自定义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;
    }
}