簡體   English   中英

從控制器內獲取控制器和動作名稱?

[英]Get controller and action name from within controller?

對於我們的 Web 應用程序,我需要根據視圖保存獲取和顯示的項目的順序 - 或者准確地說 - 生成視圖的控制器和操作(當然還有用戶 ID,但這不是這里的重點)。

與其只是在每個控制器操作中自己提供一個標識符(以便將其用於某些與視圖相關的 DB 輸出排序),我認為從控制器和它獲取的操作方法自動創建此標識符會更安全、更容易叫自。

如何從控制器的操作方法中獲取控制器和操作的名稱? 或者我需要反思嗎?

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

以下是獲取該信息的一些擴展方法(它還包括 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;
    }
}

用法:

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

可能有用。 我需要在控制器的構造函數的動作,看來在這一點上MVC生命周期的, this還沒有初始化, ControllerContext = null 我沒有深入研究 MVC 生命周期並找到要覆蓋的適當函數名稱,而是在RequestContext.RouteData找到了該操作。

但是為了做到這一點,與構造函數中任何與HttpContext相關的用途一樣,您必須指定完整的命名空間,因為this.HttpContext還沒有被初始化。 幸運的是, System.Web.HttpContext.Current似乎是靜態的。

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

注意:可能不是訪問 HttpContext 中所有屬性的最受支持的方式,但對於 RequestContext 和 Session 它似乎在我的應用程序中工作正常。

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();
    }
}
 @this.ViewContext.RouteData.Values["controller"].ToString();

這是我到目前為止:

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

這是獲得名字的最簡單和最實用的答案:

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

要么

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

上面的代碼使用 asp.net mvc 5 進行測試。

將此添加到 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;
    }

將您的控制器實現到Basecontroller

添加局部視圖 _Breadcrumb.cshtml 並使用 @Html.Partial("_Breadcrumb") 將其添加到所有必需的頁面中

_Breadcrumb.cshtml

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

您可以像任何變量一樣從操作中獲取控制器名稱或操作名稱。 它們只是特殊的(控制器和動作)並且已經定義,所以你不需要做任何特殊的事情來獲得它們,除非告訴你需要它們。

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

或者您可以在模型中包含 controller 、 action 以獲取其中兩個和您的自定義數據。

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

這對我來說似乎很好用(到目前為止),如果您使用屬性路由也適用。

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

消除對ToString()調用的需要

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

對於我們的Web應用程序,我需要保存獲取和顯示的項目的順序,具體取決於視圖-確切地說,是生成視圖的控制器和操作(當然還有用戶ID,但這不是重點)。

我認為不僅要在每個控制器動作中自己給出一個標識符(以便將其用於與視圖有關的數據庫輸出排序),我還認為,從其獲取的控制器和動作方法中自動創建此標識符會更安全,更輕松。從。

如何從控制器的action方法中獲取控制器的名稱和動作? 還是我需要為此反思?

試試這個代碼

將此覆蓋方法添加到控制器

protected override void OnActionExecuting(ActionExecutingContext actionExecutingContext)
{
   var actionName = actionExecutingContext.ActionDescriptor.ActionName;
   var controllerName = actionExecutingContext.ActionDescriptor.ControllerDescriptor.ControllerName;
   base.OnActionExecuting(actionExecutingContext);
}

為什么不做一些更簡單的事情?

只需調用Request.Path ,它將返回一個由“/”分隔的字符串

然后你可以使用.Split('/')[1]來獲取控制器名稱。

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM