Görünümde veya Denetleyicide Geçerli Alan Adını Alın


126

Görünümde veya denetleyicide geçerli alan adını nasıl alırsınız?

ViewContext.RouteData.Values["controller"]Alanlar gibi bir şey var mı ?

Yanıtlar:


217

MVC2'den itibaren kullanabilirsiniz ViewContext.RouteData.DataTokens["area"]


22
Bir alanda değilse, ViewContext.RouteData.DataTokens ["alan"] == null.
user202448

23
... ve MVC5'te :)
Stefan

4
Lol .. şaka sana @Dante ... adil olmak gerekirse ASP.NET Core 1.0yerine çağrıldı MVC6.. :-)
Rosdi Kasim

Bilginize - ajax POST'umda neyin yanlış olduğunu anladım ... lütfen ajax isteklerinin URL alanında alana sahip olup olmadığını kontrol edin ... yine de bulabilirler !!! görünüm, ancak istek yapıldığında url alanı eksikse alanı korumazlar.
Seabizkit

43
HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"]

3
Bir görünümde veya denetleyicide değilseniz, alan bilgilerini almanın en iyi ve evrensel yolu budur. Bunu gönderdiğiniz için teşekkürler!
2013,

19

Şunları kullanarak denetleyiciden edinebilirsiniz:

ControllerContext.RouteData.DataTokens["area"]

@ user202338 Alanlar MVC2'de tanıtıldı, bu yüzden bundan şüpheleniyorum, ancak DataTokens koleksiyonunu doldurma yöntemlerini değiştirip değiştirmediklerinden emin değilim. : Bunun gibi mesajları görüyorsunuz linki MVC2 kullanmadan hakkında konuşmak söyledi.
Matt Penner

10

ASP.NET Core 1.0'da değer şurada bulunur:

ViewContext.RouteData.Values ​​[ "alan"];


Emin misiniz? Hatırlayabildiğim kadarıyla, uygulamamızı ASP.NET Core 2.0 üzerinde çalıştırdığımızda işe yaradı ve halen ASP.NET Core 2.1'de çalışıyor (birkaç dakika önce test edildi).
zerox981

Haklısın, sadece Razor Sayfaları için çalışmıyorsun (ViewContext yok - pageModel.RouteData.Values.TryGetValue("area", out object area)onun yerine kullanılmalı)
Roman Pokrovskij

9

Bununla ilgili bir günlük girişi yazdım , daha fazla ayrıntı için bunu ziyaret edebilirsiniz, ancak cevabım aşağıda gösterilen bir Uzantı Yöntemi oluşturmaktı.

Ana tetikleyici, MVC Alanını .DataTokens öğesinden ve denetleyiciyi / eylemi .Values ​​of the RouteData.

public static MvcHtmlString TopMenuLink(this HtmlHelper htmlHelper, string linkText, string controller, string action, string area, string anchorTitle)
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
        var url = urlHelper.Action(action, controller, new { @area = area });

        var anchor = new TagBuilder("a");
        anchor.InnerHtml = HttpUtility.HtmlEncode(linkText);
        anchor.MergeAttribute("href", url);
        anchor.Attributes.Add("title", anchorTitle);

        var listItem = new TagBuilder("li");
        listItem.InnerHtml = anchor.ToString(TagRenderMode.Normal);

        if (CheckForActiveItem(htmlHelper, controller, action, area))
            listItem.GenerateId("menu_active");

        return MvcHtmlString.Create(listItem.ToString(TagRenderMode.Normal));
    }

    private static bool CheckForActiveItem(HtmlHelper htmlHelper, string controller, string action, string area)
    {
        if (!CheckIfTokenMatches(htmlHelper, area, "area"))
            return false;

        if (!CheckIfValueMatches(htmlHelper, controller, "controller"))
            return false;

        return CheckIfValueMatches(htmlHelper, action, "action");
    }

    private static bool CheckIfValueMatches(HtmlHelper htmlHelper, string item, string dataToken)
    {
        var routeData = (string)htmlHelper.ViewContext.RouteData.Values[dataToken];

        if (routeData == null) return string.IsNullOrEmpty(item);

        return routeData == item;
    }

    private static bool CheckIfTokenMatches(HtmlHelper htmlHelper, string item, string dataToken)
    {
        var routeData = (string)htmlHelper.ViewContext.RouteData.DataTokens[dataToken];

        if (dataToken == "action" && item == "Index" && string.IsNullOrEmpty(routeData))
            return true;

        if (dataToken == "controller" && item == "Home" && string.IsNullOrEmpty(routeData))
            return true;

        if (routeData == null) return string.IsNullOrEmpty(item);

        return routeData == item;
    }

Daha sonra aşağıdaki gibi uygulayabilirsiniz:

<ul id="menu">
@Html.TopMenuLink("Dashboard", "Home", "Index", "", "Click here for the dashboard.")
@Html.TopMenuLink("Courses", "Home", "Index", "Courses", "List of our Courses.")
</ul>

Bazı nedenlerden dolayı areajetonu içinde bulamıyorum Valuesama bakmam gerekiyor DataTokens... nedenini bilmiyorum.
Syska

8

RouteDataMevcut alan adını döndüren bir uzantı yöntemi oluşturdum .

public static string GetAreaName(this RouteData routeData)
{
    object area;
    if (routeData.DataTokens.TryGetValue("area", out area))
    {
        return area as string;
    }

    return null;
}

Çünkü RouteDataher ikisinde de mevcuttur ControllerContextve oyun ViewContextkumandanızdan ve görünümlerinizden erişilebilir.

Ayrıca test etmek çok kolaydır:

[TestFixture]
public class RouteDataExtensionsTests
{
    [Test]
    public void GetAreaName_should_return_area_name()
    {
        var routeData = new RouteData();
        routeData.DataTokens.Add("area", "Admin");
        routeData.GetAreaName().ShouldEqual("Admin");
    }

    [Test]
    public void GetAreaName_should_return_null_when_not_set()
    {
        var routeData = new RouteData();
        routeData.GetAreaName().ShouldBeNull();
    }
}

RouteData.DataTokensBu her zaman dahili olarak başlatıldığı için boş olup olmadığını kontrol etmeye gerek yoktur .


3

MVC Futures , AreaHelpers.GetAreaName () yöntemine sahiptir. Ancak, bu yöntemi kullanıyorsanız dikkatli olun. Uygulamanız hakkında çalışma zamanı kararları vermek için mevcut alanı kullanmak, hata ayıklaması zor veya güvenli olmayan koda yol açabilir.


1
Kontrolörler için böyle bir yöntem var mı? Bir koleksiyonda dize değişmezlerini kullanmaktan nefret ediyorum.
Erick T

denetleyici kullanımı this.GetName()ve mevcut Yöntem kullanımı içinMethodBase.GetCurrentMethod().Name
Nerdroid

3

Bunun eski olduğunu biliyorum, ancak ActionFilter gibi bir filtrede olduğunda, bağlam size alan bilgilerini kolayca sağlamaz.

Aşağıdaki kodda bulunabilir:

var routeData = filterContext.RequestContext.RouteData;

if (routeData.DataTokens["area"] != null)
    area = routeData.DataTokens["area"].ToString();

Bu nedenle, filtreContext geçersiz kılma sırasında iletilir ve doğru RouteData, RequestContext altında bulunur. Temel düzeyde bir RoutData vardır, ancak DataToken'ların sözlüğünde alan YOKTUR.


2

Görünümde alan adını almak için, ASP.NET Core MVC 2.1'de: To get area name in the view, in ASP.NET Core MVC 2.1:

@Context.GetRouteData().Values["area"]

2

Görünümde alan adını alın (.NET Core 2.2):

ViewContext?.ActionDescriptor?.RouteValues["area"]

0

Bunun çok eski bir gönderi olduğunu biliyorum, ancak Values ​​Property'ni DataTokens ile tamamen aynı şekilde kullanabiliriz

Url.RequestContext.RouteData.Values ​​["eylem"] benim için çalıştı.


0

Neden bilmiyorum ama kabul edilen cevap işe yaramıyor. Örneğin null döndürür (belki mvc hakkında, .net çekirdeğini kullanıyorum)

http: // localhost: 5000 / Yönetici / CustomerGroup

Her zaman değişkenin hatalarını gideririm ve içindeki verileri alırım.

Bunu dene. Benim için çalışıyor

var area = ViewContext.RouteData.Values["area"]

Ayrıntılı mantıksal örnek

Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";
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.