Bagaimana Anda mendapatkan nama area saat ini dalam tampilan atau pengontrol?
Apakah ada yang seperti ViewContext.RouteData.Values["controller"]
untuk area?
Bagaimana Anda mendapatkan nama area saat ini dalam tampilan atau pengontrol?
Apakah ada yang seperti ViewContext.RouteData.Values["controller"]
untuk area?
Jawaban:
Dari MVC2 dan seterusnya, Anda dapat menggunakan ViewContext.RouteData.DataTokens["area"]
ASP.NET Core 1.0
bukan MVC6
.. :-)
Anda bisa mendapatkannya dari controller menggunakan:
ControllerContext.RouteData.DataTokens["area"]
Di ASP.NET Core 1.0 nilainya ditemukan di
ViewContext.RouteData.Values ["area"];
pageModel.RouteData.Values.TryGetValue("area", out object area)
harus digunakan sebagai gantinya)
Saya baru saja menulis entri log ab tentang ini , Anda dapat mengunjungi itu untuk lebih jelasnya, tetapi jawaban saya adalah membuat Metode Ekstensi, yang ditunjukkan di bawah ini.
Penendang kuncinya adalah Anda menarik Area MVC dari .DataTokens dan pengontrol / aksi dari .Values dari 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;
}
Kemudian Anda bisa menerapkannya seperti di bawah ini:
<ul id="menu">
@Html.TopMenuLink("Dashboard", "Home", "Index", "", "Click here for the dashboard.")
@Html.TopMenuLink("Courses", "Home", "Index", "Courses", "List of our Courses.")
</ul>
area
token di Values
tetapi perlu mencari di DataTokens
... tidak tahu kenapa.
Saya membuat metode ekstensi untuk RouteData
mengembalikan nama area saat ini.
public static string GetAreaName(this RouteData routeData)
{
object area;
if (routeData.DataTokens.TryGetValue("area", out area))
{
return area as string;
}
return null;
}
Karena RouteData
tersedia di keduanya ControllerContext
danViewContext
dapat diakses di controller dan tampilan Anda.
Ini juga sangat mudah untuk diuji:
[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();
}
}
Tidak perlu memeriksa apakah RouteData.DataTokens
nol karena ini selalu diinisialisasi secara internal.
MVC Futures memiliki metode AreaHelpers.GetAreaName (). Namun, berhati-hatilah jika Anda menggunakan metode ini. Menggunakan area saat ini untuk membuat keputusan runtime tentang aplikasi Anda dapat menyebabkan kode sulit-untuk-debug atau tidak aman.
this.GetName()
dan untuk penggunaan Metode saat iniMethodBase.GetCurrentMethod().Name
Saya tahu ini sudah tua, tetapi juga, ketika dalam filter seperti ActionFilter, konteksnya tidak mudah memberi Anda informasi area.
Itu dapat ditemukan dalam kode berikut:
var routeData = filterContext.RequestContext.RouteData;
if (routeData.DataTokens["area"] != null)
area = routeData.DataTokens["area"].ToString();
Jadi filterContext diteruskan pada override dan RouteData yang benar ditemukan di bawah RequestContext. Ada RoutData di tingkat Basis, tetapi DataTokens TIDAK memiliki area dalam kamus itu.
Saya tahu ini adalah posting yang sangat sangat lama tetapi kita dapat menggunakan Properti Nilai persis dengan cara yang sama seperti DataTokens
Url.RequestContext.RouteData.Values ["action"] bekerja untuk saya.
Saya tidak tahu mengapa tetapi jawaban yang diterima tidak berfungsi. Mengembalikan null dengan misalnya (mungkin tentang MVC, saya menggunakan .net core)
Saya selalu men-debug variabel dan mengambil data dari dalamnya.
Coba ini. Ini bekerja untuk saya
var area = ViewContext.RouteData.Values["area"]
Contoh logis terperinci
Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";