How do I get the Controller and Action names from

2019-01-11 16:19发布

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

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?

9条回答
We Are One
2楼-- · 2019-01-11 16:52

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.

查看更多
一纸荒年 Trace。
3楼-- · 2019-01-11 16:54

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 HttpContextBase class

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;
    }
}
查看更多
混吃等死
4楼-- · 2019-01-11 16:56

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:

var fullUrl = Request.UrlReferrer.ToString();
<a href="@fullUrl">Back</a>
查看更多
戒情不戒烟
5楼-- · 2019-01-11 17:03

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

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"];
查看更多
混吃等死
6楼-- · 2019-01-11 17:05

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

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

if you want to go to previous action

查看更多
太酷不给撩
7楼-- · 2019-01-11 17:08

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).

查看更多
登录 后发表回答