Làm cách nào tôi có thể trả về hành động hiện tại trong chế độ xem ASP.NET MVC?


291

Tôi muốn đặt một lớp CSS trong trang chính của mình, điều này phụ thuộc vào bộ điều khiển và hành động hiện tại. Tôi có thể lấy để bộ điều chỉnh dòng qua ViewContext.Controller.GetType().Name, nhưng làm thế nào để tôi có được hành động hiện tại (ví dụ Index, Showvv)?

Câu trả lời:


83

Sử dụng ViewContextvà nhìn vào RouteDatabộ sưu tập để trích xuất cả bộ điều khiển và các yếu tố hành động. Nhưng tôi nghĩ rằng việc thiết lập một số biến dữ liệu cho biết bối cảnh ứng dụng (ví dụ: "chỉnh sửa mã" hoặc "lỗi") thay vì bộ điều khiển / hành động làm giảm sự ghép nối giữa các khung nhìn và bộ điều khiển của bạn.


bạn có thể lấy dữ liệu trong bộ điều khiển và chuyển nó để xem với DTO. stackoverflow.com/a/31749391/4293929
MstfAsan

5
đây KHÔNG phải là câu trả lời được chấp nhận, thay vào đó hãy xem câu trả lời được bình chọn nhiều nhất.
Hakan Fıstık

1
@HakamFostok Tôi vẫn cho rằng lời khuyên để thêm thông tin ngữ nghĩa vào mô hình là phương pháp tốt hơn trong mọi trường hợp hơn là dựa vào dữ liệu tuyến đường (bộ điều khiển, hành động) trong chế độ xem của bạn ngay cả khi câu trả lời khác cung cấp chi tiết hơn về cách lấy dữ liệu đó.
tvanfosson

467

Trong RC, bạn cũng có thể trích xuất dữ liệu tuyến đường như tên phương thức hành động như thế này

ViewContext.Controller.ValueProvider["action"].RawValue
ViewContext.Controller.ValueProvider["controller"].RawValue
ViewContext.Controller.ValueProvider["id"].RawValue

Cập nhật cho MVC 3

ViewContext.Controller.ValueProvider.GetValue("action").RawValue
ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
ViewContext.Controller.ValueProvider.GetValue("id").RawValue

Cập nhật cho MVC 4

ViewContext.Controller.RouteData.Values["action"]
ViewContext.Controller.RouteData.Values["controller"]
ViewContext.Controller.RouteData.Values["id"]

Cập nhật cho MVC 4.5

ViewContext.RouteData.Values["action"]
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["id"]

20
Tôi biết điều này trước ngày V2, nhưng bây giờ là ViewContext.Controller.ValueProvider.GetValue("action").RawValue+ các biến thể
Chris S

7
Cú pháp này hoạt động trong V4: (chuỗi) ViewContext.RouteData.Values ​​["action"];
kiprainey

2
Giải pháp này không hiệu quả với tôi (MVC4 + .NET Framework 4.5.1). Đối với tôi, nó hoạt động câu trả lời từ Viacheslav Smityukh: ViewContext.RouteData.Values ​​["hành động"], ViewContext.RouteData.Values ​​["điều khiển"], ViewContext.RouteData.Values ​​["id"],
Tomas Kubes

@kiprainey Trong V3.5 cũng vậy: msdn.microsoft.com/en-us/l
Pluto

2
Hãy thử: (chuỗi) HttpContext.Request.RequestContext.RouteData.Values ​​["action"];
Martin Dawson

60

Để nhận Id hiện tại trên Chế độ xem:

ViewContext.RouteData.Values["id"].ToString()

Để có được bộ điều khiển hiện tại:

ViewContext.RouteData.Values["controller"].ToString() 

1
ViewContext.RouteData.Values ​​[<key>]. ToString () ném ngoại lệ nếu giá trị không tồn tại trong RouteData
Phần mềm Grizzly Peak

@ShaneLarson Chỉ cần so sánh với null hoặc kiểm tra ViewContext.RouteData.Values.ContainsKey(<key>)trước.
Sao Diêm Vương

40

Tôi biết đây là một câu hỏi cũ hơn, nhưng tôi đã thấy nó và tôi nghĩ rằng bạn có thể quan tâm đến một phiên bản thay thế hơn là để cho chế độ xem của bạn xử lý lấy dữ liệu cần thiết để thực hiện công việc đó.

Theo tôi, một cách dễ dàng hơn là ghi đè phương thức OnActionExecuting . Bạn được thông qua ActionExecutingContext có chứa thành viên ActionDescriptor mà bạn có thể sử dụng để lấy thông tin mà bạn đang tìm kiếm, đó là ActionName và bạn cũng có thể truy cập Trình điều khiển và nó có chứa Trình điều khiển.

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    ActionDescriptor actionDescriptor = filterContext.ActionDescriptor;
    string actionName = actionDescriptor.ActionName;
    string controllerName = actionDescriptor.ControllerDescriptor.ControllerName;
    // Now that you have the values, set them somewhere and pass them down with your ViewModel
    // This will keep your view cleaner and the controller will take care of everything that the view needs to do it's job.
}

Hi vọng điêu nay co ich. Nếu bất cứ điều gì, ít nhất nó sẽ hiển thị một thay thế cho bất kỳ ai khác đến bằng câu hỏi của bạn.


đề nghị tốt đẹp; đã giúp tôi thực hiện điều khiển / cảm biến hành động một cách thông minh. Cảm ơn!
effkay

Bắt hành động desrciptor là những gì tôi cần, tôi không thể tìm thấy bất kỳ giải pháp nào khác vì vậy tôi chỉ cần thực hiện ở đây và sau đó chuyển những gì tôi muốn vào trong khung ngắm.
Chris Marisic

17

Tôi thấy các câu trả lời khác nhau và đưa ra một người trợ giúp lớp:

using System;
using System.Web.Mvc;

namespace MyMvcApp.Helpers {
    public class LocationHelper {
        public static bool IsCurrentControllerAndAction(string controllerName, string actionName, ViewContext viewContext) {
            bool result = false;
            string normalizedControllerName = controllerName.EndsWith("Controller") ? controllerName : String.Format("{0}Controller", controllerName);

            if(viewContext == null) return false;
            if(String.IsNullOrEmpty(actionName)) return false;

            if (viewContext.Controller.GetType().Name.Equals(normalizedControllerName, StringComparison.InvariantCultureIgnoreCase) &&
                viewContext.Controller.ValueProvider.GetValue("action").AttemptedValue.Equals(actionName, StringComparison.InvariantCultureIgnoreCase)) {
                result = true;
            }

            return result;
        }
    }
}

Vì vậy, trong Chế độ xem (hoặc chính / bố cục), bạn có thể sử dụng nó như vậy (Cú pháp dao động):

            <div id="menucontainer">

                <ul id="menu">
                    <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("home", "index", ViewContext)) {
                            @:class="selected"
                        }>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("account","logon", ViewContext)) {
                            @:class="selected"
                        }>@Html.ActionLink("Logon", "Logon", "Account")</li>
                    <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("home","about", ViewContext)) {
                            @:class="selected"
                        }>@Html.ActionLink("About", "About", "Home")</li>
                </ul>

            </div>

Hy vọng nó giúp.


15

Bạn có thể lấy những dữ liệu này từ RouteData của ViewContext

ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]

9

Trong MVC, bạn nên cung cấp cho View tất cả dữ liệu, không để View thu thập dữ liệu của chính nó, vì vậy điều bạn có thể làm là đặt lớp CSS trong hành động điều khiển của bạn.

ViewData["CssClass"] = "bold";

và chọn ra giá trị này từ ViewData trong Chế độ xem của bạn


Đây cũng là phương pháp ưa thích của tôi để giữ cho các khung nhìn không phụ thuộc vào cấu trúc bộ điều khiển, nhưng nó có thể được thực hiện theo cách khác.
tvanfosson

1
Không chắc chắn tôi sẽ đặt tên cho nó là "CssClass" vì điều đó dường như cho thấy logic hiển thị đang len lỏi vào bộ điều khiển của bạn.
tvanfosson

Đồng ý, tôi thường làm một cái gì đó như "Bối cảnh", vì vậy nó không bị ràng buộc với lớp trình bày và không bị phá vỡ nếu bạn đổi tên chế độ xem.
RedFilter

6

Tôi bỏ phiếu cho 2:

string currentActionName = ViewContext.RouteData.GetRequiredString("action");

string currentViewName = ((WebFormView)ViewContext.View).ViewPath;

Bạn có thể truy xuất cả tên vật lý của chế độ xem hiện tại và hành động đã kích hoạt nó. Nó có thể hữu ích trong các trang * .acmx một phần để xác định vùng chứa máy chủ.


2

Tôi đang sử dụng ASP.NET MVC 4 và đây là điều làm việc cho tôi:

ControllerContext.Controller.ValueProvider.GetValue("controller").RawValue
ControllerContext.Controller.ValueProvider.GetValue("action").RawValue

0

Mở rộng câu trả lời của Dale Ragan , ví dụ của anh ta để tái sử dụng, tạo một lớp ApplicationContoder xuất phát từ Trình điều khiển và đến lượt tất cả các bộ điều khiển khác của bạn xuất phát từ lớp ApplicationContoder đó thay vì Trình điều khiển.

Thí dụ:

public class MyCustomApplicationController : Controller {}

public class HomeController : MyCustomApplicationController {}

Trên ApplicationContoder mới của bạn tạo một thuộc tính có tên ExecutingAction với chữ ký này:

protected ActionDescriptor ExecutingAction { get; set; }

Và sau đó, trong phương thức OnActionExecuting (từ câu trả lời của Dale Ragan), chỉ cần gán ActionDescriptor cho thuộc tính này và bạn có thể truy cập nó bất cứ khi nào bạn cần trong bất kỳ bộ điều khiển nào.

string currentActionName = this.ExecutingAction.ActionName;

0

Ghi đè chức năng này trong bộ điều khiển của bạn

protected override void HandleUnknownAction(string actionName) 
{  TempData["actionName"] = actionName;
   View("urViewName").ExecuteResult(this.ControllerContext);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.