2012-01-12 37 views
28

Có rất nhiều thông tin để xây dựng Uris từ các tên Điều khiển và Hành động, nhưng làm cách nào tôi có thể thực hiện điều này theo cách khác?Làm cách nào để có tên Bộ điều khiển và Hành động từ Uri Liên kết?

Về cơ bản, tất cả những gì tôi đang cố gắng đạt được là lấy tên Bộ điều khiển và Hành động từ trang giới thiệu (ví dụ: Request.UrlReferrer). Có cách nào dễ dàng để đạt được điều này?

+1

http://stackoverflow.com/questions/7087663/getting-the-names-of-previous-action-and-controller-in-mvc- Bộ điều khiển – Maheep

Trả lời

45

Tôi nghĩ rằng điều này sẽ làm các trick:

// 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 của tôi là hiện nay xuống vì vậy tôi không thể kiểm tra nó, nhưng nó phải làm việc như mong đợi.

+2

Bạn có thể muốn chỉnh sửa mã này một chút. Nếu liên kết giới thiệu của bạn không có chuỗi truy vấn, bạn sẽ cố gắng gọi fullUrl.Substring (0, -1). – rossisdead

+1

@rossisdead. làm xong. cảm ơn vì tiền hỗ trợ. – gdoron

+0

Đối với tôi, tôi không thể lấy tên khu vực theo cách bạn mô tả từ 'routeData.Values', Thay vào đó tôi đã sử dụng' routeData.DataTokens ["area"] '. – Leigh

3

Đối tượng RouteData có thể truy cập thông tin này:

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

Điều đó sẽ cung cấp cho bạn dữ liệu hiện tại, không phải dữ liệu trước đó. – gdoron

+0

http://stackoverflow.com/a/31749391/4293929 – MstfAsan

0

Tôi không tin có bất kỳ cách built-in để lấy Controller/Hành động gọi phương pháp trước đó. Những gì bạn luôn có thể làm là bọc các bộ điều khiển và các phương thức hành động để chúng được lưu trong một kho lưu trữ dữ liệu liên tục, và sau đó khi bạn yêu cầu phương thức Controller/Action cuối cùng, chỉ cần lấy nó từ cơ sở dữ liệu (hoặc bất cứ thứ gì bạn chọn).

0

Đây là một phương pháp tôi đã thực hiện để trích xuất url đơn giản hóa từ giới thiệu vì tôi đã có token (kết thúc với ")) /") trong URL của tôi, do đó bạn có thể trích xuất dễ dàng điều khiển và hành động từ này:

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

Tại sao bạn cần phải xây dựng ActionLink từ url? Mục đích của ActionLink là ngược lại để tạo một url từ một số dữ liệu. Vì vậy, trong trang của bạn chỉ cần làm:

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

Để thêm vào câu trả lời được chấp nhận của gdoran, tôi thấy rằng hành động không được điền nếu thuộc tính tuyến đường tùy chỉnh được sử dụng. Các công trình sau đây cho tôi:

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

@ giải pháp gordon của công trình, nhưng bạn cần phải sử dụng

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

nếu bạn muốn đi đến hành động trước

2

Để mở rộng về câu trả lời gdoron, những Uri lớp học có các phương pháp để lấy các phần bên trái và bên phải của URL mà không phải thực hiện phân tích cú pháp chuỗi:

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"]; 
+1

sử dụng 'querystring = Request.UrlReferre.GetComponents (UriComponents.Query, UriFormat.UriEscaped);' cho chuỗi truy vấn thay thế. –

0

Tôi biết bài đăng này cũ nhưng tôi nghĩ điều này thật tuyệt.

Nếu bạn có một ý tưởng về cách tuyến đường của bạn được thiết lập bạn có thể làm:

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

tôi đã sử dụng nó để xác định xem tôi phải tải lại một bố cục hay không:

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 

Đối tôi, refererPaths (2) luôn là bộ điều khiển của tôi. Nếu có một hành động được chỉ định sau bộ điều khiển, tôi chỉ cần xóa "/" khỏi phân đoạn và sau đó tôi so sánh bộ điều khiển liên kết giới thiệu với bộ điều khiển hiện tại.

0

Đây là một cách nhẹ để thực hiện việc này mà không cần tạo đối tượng phản hồi.

var values = RouteDataContext.RouteValuesFromUri(Request.UrlReferrer); 

var controllerName = values["controller"]; 
var actionName = values["action"]; 

Sử dụng tùy chỉnh này HttpContextBase lớp

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; 
    } 
} 
Các vấn đề liên quan