从控制器和动作名称构建Uris有很多信息,但是我怎么能这样做?
基本上,我想要实现的是从引用页面获取Controller和Action名称(即Request.UrlReferrer)。有没有一种简单的方法来实现这一目标?
答案 0 :(得分:52)
我认为这应该可以解决问题:
// 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目前已关闭,因此我无法对其进行测试,但它应该按预期工作。
答案 1 :(得分:3)
为了扩展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"];
答案 2 :(得分:2)
要添加到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";
}
答案 3 :(得分:1)
RouteData对象可以访问此信息:
var controller = RouteData.Values["controller"].ToString();
var action = RouteData.Values["action"].ToString();
答案 4 :(得分:1)
@ gordon的解决方案有效,但您需要使用
return RedirectToAction(actionName.ToString(), controllerName.ToString(),values);
如果你想进行上一步行动
答案 5 :(得分:0)
我不相信有任何内置方法可以检索以前的Controller / Action方法调用。您可以随时做的是包装控制器和操作方法,以便将它们记录在持久数据存储中,然后当您需要最后一个Controller / Action方法时,只需从数据库中检索它(或者您选择的任何方式)。 / p>
答案 6 :(得分:0)
这是我通过引用来简化提取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;
}
答案 7 :(得分:0)
为什么需要从URL构建ActionLink? ActionLink的目的与从某些数据创建URL相反。所以在你的页面中只需:
var fullUrl = Request.UrlReferrer.ToString();
<a href="@fullUrl">Back</a>
答案 8 :(得分:0)
这是一种轻量级的方法,可以在不创建响应对象的情况下执行此操作。
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;
}
}