Как я могу получить имена контроллеров и действий от реферера Uri? - PullRequest
31 голосов
/ 12 января 2012

Существует много информации для создания Uris из имен Controller и Action, но как я могу сделать это наоборот?

По сути, все, чего я пытаюсь добиться, - это получить имена контроллеров и действий со ссылающейся страницы (т.е. Request.UrlReferrer). Есть ли простой способ добиться этого?

Ответы [ 9 ]

53 голосов
/ 12 января 2012

Я думаю, что это должно сработать:

// 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 в данный момент не работает, поэтому я не смог ее протестировать, но она должна работать как положено.

3 голосов
/ 30 июня 2017

Чтобы расширить ответ гдорона, класс 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 голосов
/ 20 ноября 2014

Чтобы добавить к принятому ответу 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";
}
1 голос
/ 19 октября 2015
Решение

@ Гордона работает, но вам нужно использовать

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

если вы хотите перейти к предыдущему действию

1 голос
/ 12 января 2012

Объект RouteData может получить доступ к этой информации:

 var controller = RouteData.Values["controller"].ToString();
 var action = RouteData.Values["action"].ToString();
0 голосов
/ 26 июля 2017

Вот простой способ сделать это без создания объектов ответа.

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;
    }
}
0 голосов
/ 26 декабря 2013

Зачем вам нужно создавать ActionLink из URL?Цель ActionLink как раз наоборот - сделать URL из некоторых данных.Так что на своей странице просто сделайте:

var fullUrl = Request.UrlReferrer.ToString();
<a href="@fullUrl">Back</a>
0 голосов
/ 02 октября 2013

Это метод, который я сделал для извлечения URL-адреса, упрощенного из реферера, потому что у меня был токен (закончен с ")) /") в моем URL, чтобы вы могли легко извлечь контроллер и действие из этого:

0 голосов
/ 12 января 2012

Я не верю, что есть какой-либо встроенный способ получить предыдущий вызов метода Controller / Action. Что вы всегда можете сделать, это обернуть контроллеры и методы действий так, чтобы они записывались в постоянное хранилище данных, а затем, когда вам потребуется последний метод Controller / Action, просто извлеките его из базы данных (или чего бы вы ни выбрали).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...