Получить контроллер и имя действия из контроллера?

Для нашего веб-приложения мне нужно сохранить порядок выбранных и отображаемых элементов в зависимости от представления - или, если быть точным, - контроллера и действия, которые генерировали представление (и идентификатор пользователя, конечно, но это не точка здесь).

Вместо того, чтобы просто указывать идентификатор в каждом действии контроллера (чтобы использовать его для некоторой сортировки выходов DB, ​​зависящей от вида), я думал, что было бы безопаснее и проще создавать этот идентификатор автоматически из контроллера и действия метод, из которого он вызван.

Как я могу получить имя контроллера и действия из метода действия в контроллере? Или мне нужно размышление? Я думаю, это довольно легко, спасибо заранее!

Ответ 1

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

Ответ 2

Вот некоторые методы расширения для получения этой информации (она также включает идентификатор):

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();

Ответ 3

Может быть полезно. Мне понадобилось действие в конструкторе конструктора контроллера, и он появляется в этой точке жизненного цикла 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 он отлично работает в моем приложении.

Ответ 4

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

Ответ 5

Это то, что у меня есть до сих пор:

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

Ответ 6

Вы можете получить имя контроллера или имя действия из действия, как любая переменная. Они просто специальные (контроллер и действие) и уже определены, поэтому вам не нужно делать ничего особенного, чтобы получить их, за исключением того, что вам нужно их.

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

Или вы можете включить контроллер, действие в своих моделях, чтобы получить два из них и свои пользовательские данные.

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

Ответ 7

Кажется, что это хорошо работает для меня (пока), также работает, если вы используете маршрутизацию атрибутов.

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

Ответ 8

 @this.ViewContext.RouteData.Values["controller"].ToString();

Ответ 9

Чтобы удалить необходимость ToString() использовать вызов

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

Ответ 10

Добавьте это в свой базовый контроллер внутри метода 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.cshtml

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

Ответ 11

Вот самый простой и практичный ответ на получение имени:

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

или

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

Код выше тестов с asp.net mvc 5.

Ответ 12

Используйте заданные строки в имени OnActionExecuting for Action и Controller.

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

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

Ответ 13

Почему бы не сделать что-то более простое?

Просто вызовите Request.Path, он вернет строку, разделенную "/"

а затем вы можете использовать .Split('/')[1] для получения имени контроллера.

введите описание изображения здесь