Nhận bộ điều khiển và tên hành động từ bên trong bộ điều khiển?


173

Đối với ứng dụng web của chúng tôi, tôi cần lưu thứ tự của các mục được tìm nạp và hiển thị tùy thuộc vào chế độ xem - hoặc chính xác - bộ điều khiển và hành động tạo ra chế độ xem (và tất nhiên là id người dùng, nhưng đó không phải là điểm ở đây).

Thay vì chỉ tự đưa ra một mã định danh trong mỗi hành động của bộ điều khiển (để sử dụng nó cho một số sắp xếp đầu ra DB phụ thuộc vào chế độ xem), tôi nghĩ rằng sẽ tự động an toàn và dễ dàng hơn để tạo định danh này từ bộ điều khiển và phương thức hành động. gọi từ.

Làm thế nào tôi có thể nhận được tên của bộ điều khiển và hành động từ bên trong phương thức hành động trong bộ điều khiển? Hay tôi cần sự phản ánh cho điều đó? Tôi đoán nó khá dễ, cảm ơn trước!


1
Sự phản chiếu sẽ cung cấp cho bạn tên phương thức xử lý hành động, nhưng có lẽ bạn thích tên hành động như được trả về bởi mã của Andrei.
citykid

Về cơ bản, tôi chỉ cần một mã định danh rõ ràng cho mọi hành động mang lại một khung nhìn, vì vậy cả hai cách sẽ thực hiện công việc. Nhưng bạn đã đúng, câu trả lời của Andre chắc chắn thanh lịch hơn.
Alex

@citykid Có trường hợp nào khác nhau về cách cư xử khác với trường hợp và hậu tố "Trình điều khiển" cho tên lớp không?
Giăng

@John, ActionNameAttribution cho phép phương thức ac # có bất kỳ tên hành động nào: msdn.microsoft.com/en-us/l
Library / trộm

@citykid ơi, được rồi. Đó là một tính năng lỗi thời cho rằng bạn có thể chỉ định các tuyến đường với một Routethuộc tính trên phương thức hành động tôi thu thập? Ngoài ra, nó cũng có thể đổi tên bộ điều khiển?
John

Câu trả lời:


345
string actionName = this.ControllerContext.RouteData.Values["action"].ToString();
string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();

13
Trong một số trường hợp bạn có thể muốn có tên của bộ điều khiển trong tệp View, thì bạn chỉ có thể sử dụng cái này.ViewContext.RouteData.Values ​​["controller"]. ToString ();
Amogh Natu

Nếu bạn sẽ làm điều này (cung cấp tên hành động và trình điều khiển), tại sao không chỉ định chúng trực tiếp ???
MetalPhoenix

1
@MetalPhoenix, bạn có thể nói rõ một chút về trường hợp sử dụng mà bạn đang nói đến không? OP không cần gán bộ điều khiển hoặc hành động - họ chỉ cần hiểu, theo cách chung, bộ điều khiển và hành động hiện đang được xử lý là gì.
Andrei

1
Trong lần đọc thứ hai, có thể là tôi đã hiểu nhầm đoạn mã ở đây? ... Giá trị ["hành động"] trong đó "hành động" là một khóa và không phải là tên của hành động được thay thế (như "'Pass123" mà không có dấu ngoặc kép "của sự vật)? Điều đó có nghĩa là: vẫn sẽ là Giá trị ["hành động"] thay vì Giá trị ["yourAction"]?
MetalPhoenix

@MetalPhoenix, chính xác, "hành động" theo nghĩa đen là một chìa khóa và Giá trị ["hành động"] sẽ xuất ra "CurrentActionName"
Andrei

62

Dưới đây là một số phương pháp mở rộng để nhận thông tin đó (nó cũng bao gồm ID):

public static class HtmlRequestHelper
{
    public static string Id(this HtmlHelper htmlHelper)
    {
        var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;

        if (routeValues.ContainsKey("id"))
            return (string)routeValues["id"];
        else if (HttpContext.Current.Request.QueryString.AllKeys.Contains("id"))
            return HttpContext.Current.Request.QueryString["id"];

        return string.Empty;
    }

    public static string Controller(this HtmlHelper htmlHelper)
    {
        var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;

        if (routeValues.ContainsKey("controller"))
            return (string)routeValues["controller"];

        return string.Empty;
    }

    public static string Action(this HtmlHelper htmlHelper)
    {
        var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;

        if (routeValues.ContainsKey("action"))
            return (string)routeValues["action"];

        return string.Empty;
    }
}

Sử dụng:

@Html.Controller();
@Html.Action();
@Html.Id();

1
Giải pháp tốt nhất và hoàn chỉnh, Cảm ơn Jhon
Umar Abbas

24

Có thể hữu ích. Tôi cần hành động trong hàm tạo của bộ điều khiển và nó xuất hiện tại điểm này của vòng đời MVC, thischưa được khởi tạo và ControllerContext = null. Thay vì đi sâu vào vòng đời MVC và tìm tên hàm thích hợp để ghi đè, tôi chỉ tìm thấy hành động trong RequestContext.RouteData.

Nhưng để làm như vậy, như với bất kỳ việc HttpContextsử dụng liên quan nào trong hàm tạo, bạn phải chỉ định không gian tên đầy đủ, vì this.HttpContextcũng chưa được khởi tạo. May mắn thay, nó xuất hiện System.Web.HttpContext.Currentlà tĩnh.

// controller constructor
public MyController() {
    // grab action from RequestContext
    string action = System.Web.HttpContext.Current.Request.RequestContext.RouteData.GetRequiredString("action");

    // grab session (another example of using System.Web.HttpContext static reference)
    string sessionTest = System.Web.HttpContext.Current.Session["test"] as string
}

LƯU Ý: có thể không phải là cách được hỗ trợ nhiều nhất để truy cập tất cả các thuộc tính trong HttpContext, nhưng đối với RequestContext và Phiên thì nó có vẻ hoạt động tốt trong ứng dụng của tôi.


11
var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;
if (routeValues != null) 
{
    if (routeValues.ContainsKey("action"))
    {
        var actionName = routeValues["action"].ToString();
                }
    if (routeValues.ContainsKey("controller"))
    {
        var controllerName = routeValues["controller"].ToString();
    }
}


4

Đây là những gì tôi có cho đến nay:

var actionName = filterContext.ActionDescriptor.ActionName;
var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;

3

Đây là câu trả lời đơn giản và thiết thực nhất để có được một cái tên:

var actionName = RouteData.Values["action"];
var controllerName = RouteData.Values["controller"];

Hoặc là

string actionName = RouteData.Values["action"].ToString();
string controllerName = RouteData.Values["controller"].ToString();

Mã trên kiểm tra với asp.net mvc 5.


2

Thêm phần này vào bộ điều khiển cơ sở của bạn bên trong phương thức GetDefaults ()

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
         GetDefaults();
         base.OnActionExecuting(filterContext);
    }

    private void GetDefaults()
    {
    var actionName = filterContext.ActionDescriptor.ActionName;
    var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
    }

Triển khai bộ điều khiển của bạn để sở

Thêm chế độ xem một phần _Breadcrumb.cshtml và thêm nó vào tất cả các trang bắt buộc với @ Html.Partial ("_ Breadcrumb")

_Breadcrumb.cshtml

<span>
    <a href="../@ViewData["controllerName"]">
        @ViewData["controllerName"]
    </a> > @ViewData["actionName"]
</span>

(1): Đây có phải vẫn là một trong những cách phổ biến nhất trong MVC5 không? (2) Nơi nào bạn nhận được filterContextbiến của bạn từ bên trong GetDefaults()?
chriszo111

1

Bạn có thể lấy tên bộ điều khiển hoặc tên hành động từ hành động như bất kỳ biến nào. Chúng chỉ là đặc biệt (bộ điều khiển và hành động) và đã được xác định, do đó bạn không cần phải làm gì đặc biệt để có được chúng ngoại trừ việc bạn cần chúng.

public string Index(string controller,string action)
   {
     var names=string.Format("Controller : {0}, Action: {1}",controller,action);
     return names;
   }

Hoặc bạn có thể bao gồm bộ điều khiển, hành động trong các mô hình của mình để lấy hai trong số chúng và dữ liệu tùy chỉnh của bạn.

public class DtoModel
    {
        public string Action { get; set; }
        public string Controller { get; set; }
        public string Name { get; set; }
    }

public string Index(DtoModel baseModel)
    {
        var names=string.Format("Controller : {0}, Action: {1}",baseModel.Controller,baseModel.Action);
        return names;
    }

1

Điều này dường như hoạt động độc đáo đối với tôi (cho đến nay), cũng hoạt động nếu bạn đang sử dụng định tuyến thuộc tính.

public class BaseController : Controller
{
    protected string CurrentAction { get; private set; }
    protected string CurrentController { get; private set; }

    protected override void Initialize(RequestContext requestContext)
    {
        this.PopulateControllerActionInfo(requestContext);
    }

    private void PopulateControllerActionInfo(RequestContext requestContext)
    {
        RouteData routedata = requestContext.RouteData;

        object routes;

        if (routedata.Values.TryGetValue("MS_DirectRouteMatches", out routes))
        {
            routedata = (routes as List<RouteData>)?.FirstOrDefault();
        }

        if (routedata == null)
            return;

        Func<string, string> getValue = (s) =>
        {
            object o;
            return routedata.Values.TryGetValue(s, out o) ? o.ToString() : String.Empty;
        };

        this.CurrentAction = getValue("action");
        this.CurrentController = getValue("controller");
    }
}

1

Để loại bỏ nhu cầu ToString()sử dụng cuộc gọi

string actionName = ControllerContext.RouteData.GetRequiredString("action");
string controllerName = ControllerContext.RouteData.GetRequiredString("controller");

1

Sử dụng các dòng nhất định trong OnActionExecuting cho hành động và tên Trình điều khiển.

chuỗi actionName = this.ControllContext.RouteData.Values ​​["action"]. ToString ();

chuỗi controlName = this.ControllContext.RouteData.Values ​​["control"]. ToString ();


-8

Tại sao không có một cái gì đó đơn giản hơn?

Chỉ cần gọi Request.Path, nó sẽ trả về một Chuỗi được phân tách bằng dấu "/"

và sau đó bạn có thể sử dụng .Split('/')[1]để lấy Tên điều khiển.

nhập mô tả hình ảnh ở đây


1
-1: với mã của bạn, các ứng dụng cấp phụ đơn giản bị bỏ qua (ví dụ http://www.example.com/sites/site1/controllerA/actionB/:). MVC cung cấp một loạt các API để định tuyến, vậy tại sao bạn cần phân tích lại (một lần nữa) URL?.
T-moty

Tại sao phải phát minh lại bánh xe và hơn nữa, với khả năng phục hồi kém? Điều này không làm việc cho tất cả các trường hợp.
jstuardo

Ngoài các thư mục con, vấn đề thực sự là bạn có thể tùy chỉnh các tuyến đường của mình để chúng luôn luôn như vậycontroller/action
drzaus
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.