Подтвердить что ты не робот

Как получить имена Controller и Action из Referrer Uri?

Там много информации для создания Uris из имен Controller и Action, но как я могу сделать это по-другому?

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

Чтобы добавить к принятому ответу 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";
}

Ответ 4

Решение @gordon работает, но вам нужно использовать

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

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

Ответ 5

Чтобы расширить ответ 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"];

Ответ 6

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

Ответ 7

Это метод, который я сделал, чтобы извлечь URL-адрес, упрощенный от referrer, потому что у меня был маркер (завершен с "))/" ) в моем 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;
    }

Ответ 8

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

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

Ответ 9

Я знаю, что этот пост старый, но я думал, что это круто.

Если у вас есть идея о том, как настроен ваш маршрут, вы можете:

Dim reffererPaths As String() = Request.UrlReferrer.Segments

Я использовал его, чтобы определить, нужно ли перезагружать макет или нет:

Function YourAction() As ActionResult
        Dim refererPaths As String() = Request.UrlReferrer.Segments
        Dim controller As String = RouteData.Values("controller").ToString()

        If refererPaths(2).Replace("/", "") <> controller Then
            Return View("YourAction", "SpecificLayout")
        End If

        Return View()
    End Function

Для меня refererPaths (2) всегда был моим контроллером. Если после контроллера было указано действие, я просто удалил "/" из сегмента, а затем сравнил контроллер referrer с текущим контроллером.

Ответ 10

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

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