Pour notre application Web, je dois enregistrer l'ordre des éléments récupérés et affichés en fonction de la vue - ou plus précisément - du contrôleur et de l'action qui a généré la vue (et l'identifiant de l'utilisateur, bien sûr, mais ce n'est pas le problème ici).
Au lieu de me donner moi-même un identifiant dans chaque action du contrôleur (afin de l'utiliser pour un tri des sorties de base de données dépendant de la vue), j'ai pensé qu'il serait plus sûr et plus facile de créer cet identifiant automatiquement à partir du contrôleur et de la méthode d'action qu'il obtient. appelé de.
Comment obtenir le nom du contrôleur et l'action à partir de la méthode d'action dans un contrôleur? Ou ai-je besoin de réflexion pour cela? Je suppose que c'est assez facile, merci d'avance!
string actionName = this.ControllerContext.RouteData.Values["action"].ToString();
string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();
Voici quelques méthodes d'extension pour obtenir ces informations (cela inclut également l'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;
}
}
Usage:
@Html.Controller();
@Html.Action();
@Html.Id();
Pourrait être utile. J'avais besoin de l'action dans le constructeur du contrôleur, et cela apparaît à ce stade du cycle de vie du MVC, this
n'a pas été initialisé et ControllerContext = null
. Au lieu de fouiller dans le cycle de vie de MVC et de trouver le nom de fonction approprié à remplacer, je viens de trouver l'action dans RequestContext.RouteData
.
Mais pour ce faire, comme pour toutes les utilisations liées au HttpContext
dans le constructeur, vous devez spécifier l’espace de nom complet, car this.HttpContext
n’a pas non plus été initialisé. Heureusement, il semble que System.Web.HttpContext.Current
soit statique.
// 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
}
REMARQUE: ce n'est probablement pas le moyen le plus compatible d'accéder à toutes les propriétés dans HttpContext, mais pour RequestContext et Session, il semble fonctionner correctement dans mon application.
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();
}
}
C'est ce que j'ai jusqu'ici:
var actionName = filterContext.ActionDescriptor.ActionName;
var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
@this.ViewContext.RouteData.Values["controller"].ToString();
Vous pouvez obtenir le nom du contrôleur ou le nom de l'action à partir de l'action comme n'importe quelle variable. Ils sont juste spéciaux (contrôleur et action) et déjà définis, vous n'avez donc rien à faire de spécial pour les obtenir, sauf vous dire que vous en avez besoin.
public string Index(string controller,string action)
{
var names=string.Format("Controller : {0}, Action: {1}",controller,action);
return names;
}
Ou vous pouvez inclure un contrôleur, une action dans vos modèles pour en obtenir deux et vos données personnalisées.
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;
}
Utilisez les lignes données dans OnActionExecuting pour Action et nom du contrôleur.
string actionName = this.ControllerContext.RouteData.Values ["action"]. ToString ();
string controllerName = this.ControllerContext.RouteData.Values ["controller"]. ToString ();
Cela semble bien fonctionner pour moi (jusqu'à présent), fonctionne également si vous utilisez le routage d'attribut.
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");
}
}
Voici la réponse la plus simple et la plus pratique pour obtenir un nom:
var actionName = RouteData.Values["controller"];
var controllerName = RouteData.Values["action"];
Ou
string actionName = RouteData.Values["controller"].ToString();
string controllerName = RouteData.Values["action"].ToString();
Code ci-dessus des tests avec asp.net mvc 5.
Pour supprimer le besoin de ToString()
appel, utilisez
string actionName = ControllerContext.RouteData.GetRequiredString("action");
string controllerName = ControllerContext.RouteData.GetRequiredString("controller");
Ajoutez ceci à votre contrôleur de base dans la méthode 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;
}
Implémentez vos contrôleurs pour Basecontroller
Ajoutez une vue partielle _Breadcrumb.cshtml et ajoutez-la dans toutes les pages requises avec @ Html.Partial ("_ Breadcrumb")
_ Breadcrumb.cshtml
<span>
<a href="../@ViewData["controllerName"]">
@ViewData["controllerName"]
</a> > @ViewData["actionName"]
</span>