Как получить имена Controller и Action из Referrer Uri?
Там много информации для создания Uris из имен Controller и Action, но как я могу сделать это по-другому?
В принципе, все, чего я пытаюсь достичь, - это получить имена Controller и Action со ссылочной страницы (т.е. Request.UrlReferrer). Есть ли простой способ достичь этого?
Ответы
Ответ 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;
}
}