Denetleyici ve eylem adı denetleyiciden alınsın mı?


173

Web uygulamamız için, görünüme bağlı olarak getirilen ve görüntülenen öğelerin sırasını kaydetmeliyim - ya da kesin olarak - görünümü oluşturan denetleyici ve eylem (ve elbette kullanıcı kimliği, ancak buradaki nokta değil).

Her denetleyici eyleminde kendime bir tanımlayıcı vermek yerine (DB çıktılarının görünüme bağlı sıralaması için kullanmak için), bu tanımlayıcıyı otomatik olarak denetleyiciden ve eylem yönteminden otomatik olarak oluşturmanın daha güvenli ve daha kolay olacağını düşündüm denilen.

Denetleyicinin ve eylemin adını denetleyicideki eylem yönteminden nasıl alabilirim? Yoksa bunun için düşünmeye mi ihtiyacım var? Sanırım çok kolay, şimdiden teşekkürler!


1
Yansıma size eylemi işleyen yöntem adını verir, ancak büyük olasılıkla Andrei'nin kodu tarafından döndürülen eylem adını tercih edersiniz.
citykid

Temelde sadece bir görünüm sunan her eylem için açık bir tanımlayıcıya ihtiyacım var, bu yüzden her iki yol da işi yapardı. Ama haklısın, Andrei'nin cevabı kesinlikle daha zarif.
Alex

@citykid Bunların durum ve sınıf isimleri için "Denetleyici" soneki dışındaki biçimlerde farklılık gösterdiği durumlar var mı?
John

@John, ActionNameAttribute, ac # yönteminin herhangi bir işlem adına sahip olmasına izin verir: msdn.microsoft.com/en-us/library/…
citykid

@citykid Oh, tamam. Topladığım Routeeylem yönteminde bir özniteliğe sahip yolları belirtebileceğiniz göz önüne alındığında, bu eski bir özellik mi? Ayrıca, denetleyicileri yeniden adlandırmak da mümkün müdür?
John

Yanıtlar:


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

13
Görünüm dosyasında denetleyicinin adını kullanmak isteyebileceğiniz bazı durumlarda, bu.ViewContext.RouteData.Values ​​["controller"] .ToString ();
Amogh Natu

Bunu yapacaksanız (eylem ve denetleyici adını girin), neden sadece doğrudan atamıyorsunuz ???
MetalPhoenix

1
@MetalPhoenix, bahsettiğiniz kullanım durumunu biraz açıklayabilir misiniz? OP'nin kontrolör veya eylem ataması gerekmez - sadece genel olarak, şu anda işlenmekte olan kontrolör ve eylemin ne olduğunu anlamaları gerekir.
Andrei

1
İkinci bir okumada, kod pasajını burada yanlış anlamam mümkün mü? ... Değerler "" eylem "] Burada" eylem ", değiştirilecek eylemin adı değil, bir anahtardır (" şey türü "tırnak işaretleri olmadan" 'Pass123 "gibi)? Yani: Değerler ["eyleminiz"] yerine yine Değerler ["eylem"] olur mu?
MetalPhoenix

@MetalPhoenix, tam olarak, "eylem" değişmezi bir anahtardır ve Değerler ["eylem"] "CurrentActionName" çıktısı verir
Andrei

62

Bu bilgileri almak için bazı uzantı yöntemleri şunlardır (ayrıca kimliği içerir):

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

Kullanımı:

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

1
En İyi ve Eksiksiz Çözüm, Teşekkürler Jhon
Umar Abbas

24

Yararlı olabilir. Denetleyicinin yapıcısında eyleme ihtiyacım vardı ve MVC yaşam döngüsünün bu noktasında görünüyor, thisbaşlatılmadı ve ControllerContext = null. MVC yaşam döngüsüne girmek ve geçersiz kılmak için uygun işlev adını bulmak yerine, sadece eylemi buldum RequestContext.RouteData.

Ancak bunu yapmak için, HttpContextyapıcıdaki ilgili kullanımlarda olduğu gibi , tam ad alanını belirtmeniz gerekir, çünkü this.HttpContextaynı zamanda başlatılmamıştır. Neyse ki, System.Web.HttpContext.Currentstatik görünüyor .

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

Not: büyük olasılıkla HttpContext tüm özelliklerine erişmek için en desteklenen yolu değil, ancak RequestContext ve oturum için benim uygulama iyi çalışıyor gibi görünüyor.


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

Şimdiye kadar sahip olduğum şey bu:

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

3

İşte bir isim almak için en basit ve en pratik cevap:

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

Veya

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

Yukarıdaki kod asp.net mvc 5 ile kodlayın.


2

Bunu GetDefaults () yöntemi içindeki temel denetleyicinize ekleyin

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

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

Denetleyicilerinizi Basecontroller'a uygulayın

Kısmi görünüm _Breadcrumb.cshtml ekleyin ve @ Html.Partial ile gerekli tüm sayfalara ekleyin ("_ Breadcrumb")

_Breadcrumb.cshtml

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

(1): Bu hala MVC5 içinde en yaygın yollardan biri mi? (2) filterContextDeğişkeninizi içeriden nereden alıyorsunuz GetDefaults()?
chriszo111

1

Denetleyici adını veya eylem adını herhangi bir değişken gibi eylemden alabilirsiniz. Bunlar sadece özeldir (denetleyici ve eylem) ve zaten tanımlanmıştır, bu yüzden onlara ihtiyacınız olduğunu söylemek dışında özel bir şey yapmanız gerekmez.

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

Veya bunlardan ikisini ve özel verilerinizi almak için denetleyiciyi, modellerinize eylem ekleyebilirsiniz.

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

Bu benim için güzel çalışıyor gibi görünüyor (şimdiye kadar), aynı zamanda özellik yönlendirme kullanıyorsanız da çalışır.

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

ToString()Çağrı kullanma ihtiyacını ortadan kaldırmak için

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

1

Eylem ve Denetleyici adı için OnActionExecuting'te verilen satırları kullanın.

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

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


-8

Neden daha basit bir şeye sahip olmasın?

Sadece arayın Request.Path, "/" ile ayrılmış bir String döndürecektir

ve sonra .Split('/')[1]Denetleyici Adını almak için kullanabilirsiniz .

resim açıklamasını buraya girin


1
-1: kodunuzla birlikte, alt düzey uygulamalar göz ardı edilir (örneğin:) http://www.example.com/sites/site1/controllerA/actionB/. MVC, yönlendirme için bir grup API sağlar, bu yüzden neden URL'leri (tekrar) ayrıştırmanız gerekir ?.
T-moty

Neden tekerleği yeniden icat etmek ve daha da zayıf bir yeniden doğuşla? bu tüm durumlar için geçerli değildir.
jstuardo

alt klasörlerin yanı sıra, asıl sorun, rotalarınızı her zaman olmayacak şekilde özelleştirebilmenizdircontroller/action
drzaus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.