Bir ASP.NET MVC görünümünde geçerli eylemi nasıl döndürebilirim?


291

Ana sayfamda geçerli denetleyiciye ve eyleme bağlı olarak bir CSS sınıfı ayarlamak istedim. Şu anki denetleyiciye üzerinden gidebilirim ViewContext.Controller.GetType().Name, ancak geçerli eylemi nasıl alabilirim (örn. Index, ShowVb.)?

Yanıtlar:


83

Hem denetleyiciyi hem de eylem öğelerini çıkarmak ViewContextiçin RouteDatakoleksiyonu kullanın ve bakın . Ancak, denetleyici / eylem yerine uygulama bağlamını (örneğin, "düzenleme modu" veya "hata") belirten bazı veri değişkenleri ayarlamanın, görünümleriniz ve denetleyiciler arasındaki bağlantıyı azalttığını düşünüyorum.


verileri denetleyiciye alabilir ve DTO ile görüntülemek için iletebilirsiniz. stackoverflow.com/a/31749391/4293929
MstfAsan

5
bu kabul edilen cevap OLMAMALIDIR, bunun yerine en çok oy alan cevaba bakınız.
Hakan Fıstık

1
@HakamFostok Yine de, modele semantik bilgi ekleme tavsiyesinin, diğer yanıt bu verilerin nasıl elde edileceği konusunda daha fazla ayrıntı sağlasa bile, görüşünüzdeki rota verilerine (denetleyici, eylem) güvenmekten daha iyi bir yöntem olduğunu düşünüyorum.
tvanfosson

467

RC'de ayrıca, böyle işlem yöntemi adı gibi rota verilerini de çıkarabilirsiniz

ViewContext.Controller.ValueProvider["action"].RawValue
ViewContext.Controller.ValueProvider["controller"].RawValue
ViewContext.Controller.ValueProvider["id"].RawValue

MVC 3 Güncellemesi

ViewContext.Controller.ValueProvider.GetValue("action").RawValue
ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
ViewContext.Controller.ValueProvider.GetValue("id").RawValue

MVC 4 Güncellemesi

ViewContext.Controller.RouteData.Values["action"]
ViewContext.Controller.RouteData.Values["controller"]
ViewContext.Controller.RouteData.Values["id"]

MVC 4.5 Güncellemesi

ViewContext.RouteData.Values["action"]
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["id"]

20
Bu V2 öncesi tarihleri ​​biliyorum, ama şimdi ViewContext.Controller.ValueProvider.GetValue("action").RawValue+ varyasyonları
Chris S

7
Bu sözdizimi V4'te çalışır: (string) ViewContext.RouteData.Values ​​["action"];
kiprainey

2
Bu çözüm benim için çalışmıyor (MVC4 + .NET Framework 4.5.1). Benim için Viacheslav Smityukh'ın cevabı çalışıyor: ViewContext.RouteData.Values ​​["action"], ViewContext.RouteData.Values ​​["controller"], ViewContext.RouteData.Values ​​["id"],
Tomas Kubes


2
Deneyin: (string) HttpContext.Request.RequestContext.RouteData.Values ​​["action"];
Martin Dawson

60

Geçerli Kimliği bir Görünümde almak için:

ViewContext.RouteData.Values["id"].ToString()

Geçerli denetleyiciyi almak için:

ViewContext.RouteData.Values["controller"].ToString() 

1
. Değeri RouteData içinde yoksa ViewContext.RouteData.Values [<key>] ToString () bir istisna atar
Grizzly Tepe Yazılımını

@ShaneLarson Sadece null ile karşılaştırın ya da ViewContext.RouteData.Values.ContainsKey(<key>)önce kontrol edin .
Pluto

40

Bunun daha eski bir soru olduğunu biliyorum, ama gördüm ve görüşünüzün işini yapması için gereken verileri almasına izin vermekten daha alternatif bir versiyonla ilgilenebileceğinizi düşündüm.

Bence daha kolay bir yol OnActionExecuting yöntemini geçersiz kılmak olacaktır . Aradığınız bilgileri elde etmek için kullanabileceğiniz ActionDescriptor üyesini içeren ActionExecutingContext iletilir , bu işlem ActionName'dir ve ControllerDescriptor'a da erişebilirsiniz ve ControllerName'i de içerir.

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    ActionDescriptor actionDescriptor = filterContext.ActionDescriptor;
    string actionName = actionDescriptor.ActionName;
    string controllerName = actionDescriptor.ControllerDescriptor.ControllerName;
    // Now that you have the values, set them somewhere and pass them down with your ViewModel
    // This will keep your view cleaner and the controller will take care of everything that the view needs to do it's job.
}

Bu yardımcı olur umarım. Herhangi bir şey varsa, en azından sorunuz tarafından gelen herkes için bir alternatif gösterecektir.


güzel tavsiye; denetleyici / eylem algılamasının akıllıca uygulanmasında bana yardımcı oldu. Teşekkürler!
effkay

Eylem desrciptor almak ihtiyacım olan şey, ben gerçekten burada başka bir çözüm bulamadım ve ben sadece burada yapmak ve sonra viewbag içine ne istediğini kıpırdamak.
Chris Marisic

17

Farklı cevaplar gördüm ve bir sınıf yardımcısı buldum:

using System;
using System.Web.Mvc;

namespace MyMvcApp.Helpers {
    public class LocationHelper {
        public static bool IsCurrentControllerAndAction(string controllerName, string actionName, ViewContext viewContext) {
            bool result = false;
            string normalizedControllerName = controllerName.EndsWith("Controller") ? controllerName : String.Format("{0}Controller", controllerName);

            if(viewContext == null) return false;
            if(String.IsNullOrEmpty(actionName)) return false;

            if (viewContext.Controller.GetType().Name.Equals(normalizedControllerName, StringComparison.InvariantCultureIgnoreCase) &&
                viewContext.Controller.ValueProvider.GetValue("action").AttemptedValue.Equals(actionName, StringComparison.InvariantCultureIgnoreCase)) {
                result = true;
            }

            return result;
        }
    }
}

Böylece, Görünümde (veya ana / mizanpajda) şöyle kullanabilirsiniz (Jilet sözdizimi):

            <div id="menucontainer">

                <ul id="menu">
                    <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("home", "index", ViewContext)) {
                            @:class="selected"
                        }>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("account","logon", ViewContext)) {
                            @:class="selected"
                        }>@Html.ActionLink("Logon", "Logon", "Account")</li>
                    <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("home","about", ViewContext)) {
                            @:class="selected"
                        }>@Html.ActionLink("About", "About", "Home")</li>
                </ul>

            </div>

Umarım yardımcı olur.


15

Bu verileri bir ViewContext'in RouteData öğesinden alabilirsiniz.

ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]

9

MVC'de View'e tüm verileri sağlamanız gerekir, View'un kendi verilerini toplamasına izin vermeyin, böylece yapabileceğiniz şey CSS sınıfını denetleyici eyleminizde ayarlamaktır.

ViewData["CssClass"] = "bold";

ve Görünümünüzdeki ViewData öğenizden bu değeri seçin


Bu, görünümlerin kontrolör yapısına bağlı kalmasını önlemek için de benim tercih ettiğim yöntem olurdu, ancak aksi halde yapılabilir.
tvanfosson

1
Emin değilim ben bunu "CssClass" olarak adlandıracak gibi görünen mantık denetleyicinize sürünüyor.
tvanfosson

Kabul ediyorum, genellikle "Bağlam" gibi bir şey yapıyorum, bu yüzden sunum katmanına bağlı değil ve görünümü de yeniden adlandırırsanız kırılmaz.
RedFilter

6

Bu 2'ye oy verdim:

string currentActionName = ViewContext.RouteData.GetRequiredString("action");

ve

string currentViewName = ((WebFormView)ViewContext.View).ViewPath;

Geçerli görünümün fiziksel adını ve onu tetikleyen eylemi kaldırabilirsiniz. Ana bilgisayar kapsayıcısını belirlemek için kısmi * .acmx sayfalarında yararlı olabilir.


2

ASP.NET MVC 4 kullanıyorum ve bu benim için çalıştı:

ControllerContext.Controller.ValueProvider.GetValue("controller").RawValue
ControllerContext.Controller.ValueProvider.GetValue("action").RawValue

0

Dale Ragan'ın yeniden kullanım örneği cevabını genişletmek , Controller'dan türeyen bir ApplicationController sınıfı oluşturur ve diğer tüm denetleyicilerinizin Controller yerine bu ApplicationController sınıfından türetilmesini sağlar.

Misal:

public class MyCustomApplicationController : Controller {}

public class HomeController : MyCustomApplicationController {}

Yeni ApplicationController'ınızda bu imzayla ExecutingAction adlı bir özellik oluşturun:

protected ActionDescriptor ExecutingAction { get; set; }

Ve sonra OnActionExecuting yönteminde (Dale Ragan'ın cevabından), bu özelliğe ActionDescriptor atayın ve denetleyicilerinizden herhangi birinde ihtiyacınız olduğunda ona erişebilirsiniz.

string currentActionName = this.ExecutingAction.ActionName;

0

Oyun kumandanızda bu işlevi geçersiz kıl

protected override void HandleUnknownAction(string actionName) 
{  TempData["actionName"] = actionName;
   View("urViewName").ExecuteResult(this.ControllerContext);
}
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.