Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从引用Uri获取控制器和操作名称?_C#_Asp.net Mvc 3_Razor - Fatal编程技术网

C# 如何从引用Uri获取控制器和操作名称?

C# 如何从引用Uri获取控制器和操作名称?,c#,asp.net-mvc-3,razor,C#,Asp.net Mvc 3,Razor,有很多关于从控制器和操作名构建URI的信息,但是我怎样才能反过来呢 基本上,我所要做的就是从引用页面(即Request.urlReferer)获取控制器和操作名称。有没有一种简单的方法可以实现这一点?RoutedData对象可以访问以下信息: var controller = RouteData.Values["controller"].ToString(); var action = RouteData.Values["action"].ToString(); 我不相信有任何内置方法可以

有很多关于从控制器和操作名构建URI的信息,但是我怎样才能反过来呢


基本上,我所要做的就是从引用页面(即Request.urlReferer)获取控制器和操作名称。有没有一种简单的方法可以实现这一点?

RoutedData对象可以访问以下信息:

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

我不相信有任何内置方法可以检索以前的控制器/操作方法调用。您通常可以做的是包装控制器和操作方法,以便将它们记录在持久数据存储中,然后当您需要最后一个控制器/操作方法时,只需从数据库中检索它(或您选择的任何方法)。

我想这应该可以做到:

// 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当前处于关闭状态,因此我无法对其进行测试,但它应能按预期工作。

这是一种我用来从Referer中提取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;
    }

为什么需要从url构建ActionLink?ActionLink的目的恰恰相反,它是从一些数据创建url。因此,在您的页面中,只需执行以下操作:

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

要添加到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";
}
public static void setupReferreRouteVariables(HttpRequestBase HttpRequestBase,ref string previousAreaName,ref string previousControllerName,ref string previousActionName)
{
//找不到推荐人,可能直接访问页面,请返回。
if(httpRequestBase.urlReferer==null)返回;
//将url拆分为url+QueryString。
var fullUrl=httpRequestBase.urlreferer.ToString();
var questionMarkIndex=fullUrl.IndexOf(“?”);
字符串queryString=null;
var url=fullUrl;
if(questionMarkIndex!=-1)//有一个查询字符串
{
url=fullUrl.Substring(0,questionMarkIndex);
queryString=fullUrl.Substring(questionMarkIndex+1);
}
//安排。
var request=newhttprequest(null、url、queryString);
var response=new-HttpResponse(new-StringWriter());
var httpContext=新的httpContext(请求、响应);
var routeData=RouteTable.Routes.GetRouteData(新的HttpContextWrapper(httpContext));
如果(RoutedData==null)抛出新的AuthenticationRedirectoreFerrerDataNotFoundException();
//提取数据。
var previousValues=路由数据值;
previousAreaName=previousValues[“area”]==null?字符串。空:previousValues[“area”]。ToString();
previousControllerName=previousValues[“控制器”]==null?字符串。空:previousValues[“控制器”]。ToString();
previousActionName=previousValues[“action”]==null?字符串。空:previousValues[“action”]。ToString();
if(previousActionName!=string.Empty)返回;
var routeDataAsListFromMsDirectRouteMatches=(List)先前的值[“MS_DirectRouteMatches”];
var routeValueDictionaryFromMsDirectRouteMatches=routeDataAsListFromMsDirectRouteMatches.FirstOrDefault();
if(routeValueDictionaryFromMsDirectRouteMatches==null)返回;
previousActionName=routeValueDictionaryFromMsDirectRouteMatches.Values[“action”].ToString();
如果(previousActionName==“”)previousActionName=“索引”;
}

@gordon的解决方案可行,但您需要使用

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

如果您想转到上一个操作

来扩展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"];

这里是一种轻量级的方法,可以在不创建响应对象的情况下实现这一点

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

这将为您提供当前数据,而不是以前的数据。您可能需要编辑一下此代码。如果您的引用者没有查询字符串,您将尝试调用FulrUR.Sub(0,-1)。对于我来说,我无法从“代码> RouTeDATA”的值中获得区域名称。值< /代码>,而是使用<代码> RouTeDATA。DATATOKENS(“区域”)< /代码>。(StringWriter sw=new StringWriter(CultureInfo.InvariantCulture)){}并更改为var response=new HttpResponse(sw);以避免VS代码分析抱怨StringWriter应该被处置。除了areaName之外,所有内容都在填充,这总是空的,有什么想法吗?@JsonStatham我不再使用asp.net 4.x(仅核心),但您应该检查
值中的值。使用
querystring=Request.UrlReferre.GetComponents(UriComponents.Query,UriFormat.UriEscape);
代替querystring.querystring=Request.urlReferer.GetComponents(UriComponents.Query,UriFormat.UriEscape);如果Request.urlReferer==null,则需要在调用任何方法之前检查第一行!在第一行做得很好,您正在Request.urlReferer==null中检查null,而其他答案没有这样做!