Làm thế nào để bạn có được tên khu vực hiện tại trong chế độ xem hoặc bộ điều khiển?
Có bất cứ điều gì như ViewContext.RouteData.Values["controller"]
cho các khu vực?
Làm thế nào để bạn có được tên khu vực hiện tại trong chế độ xem hoặc bộ điều khiển?
Có bất cứ điều gì như ViewContext.RouteData.Values["controller"]
cho các khu vực?
Câu trả lời:
Từ MVC2 trở đi bạn có thể sử dụng ViewContext.RouteData.DataTokens["area"]
ASP.NET Core 1.0
thay vì MVC6
.. :-)
Bạn có thể lấy nó từ bộ điều khiển bằng cách sử dụng:
ControllerContext.RouteData.DataTokens["area"]
Trong ASP.NET Core 1.0, giá trị được tìm thấy trong
ViewContext.RouteData.Values ["area"];
pageModel.RouteData.Values.TryGetValue("area", out object area)
nên được sử dụng thay thế)
Tôi vừa viết ab log entry về điều này , bạn có thể truy cập vào đó để biết thêm chi tiết, nhưng câu trả lời của tôi là tạo Phương thức mở rộng, được hiển thị bên dưới.
Yếu tố chính là bạn kéo Khu vực MVC từ .DataTokens và bộ điều khiển / hành động từ .Values của 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;
}
Sau đó, bạn có thể thực hiện nó như dưới đây:
<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
mã thông báo trong Values
nhưng cần phải tìm trong DataTokens
... không biết tại sao.
Tôi đã tạo một phương thức mở rộng để RouteData
trả về tên khu vực hiện tại.
public static string GetAreaName(this RouteData routeData)
{
object area;
if (routeData.DataTokens.TryGetValue("area", out area))
{
return area as string;
}
return null;
}
Vì RouteData
có sẵn trên cả hai ControllerContext
và ViewContext
nó có thể được truy cập trong bộ điều khiển và chế độ xem của bạn.
Nó cũng rất dễ dàng để kiểm tra:
[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();
}
}
Không cần phải kiểm tra nếu RouteData.DataTokens
là null vì điều này luôn được khởi tạo bên trong.
MVC Futures có phương thức AreaHelpers.GetAreaName (). Tuy nhiên, hãy thận trọng nếu bạn đang sử dụng phương pháp này. Sử dụng khu vực hiện tại để đưa ra quyết định thời gian chạy về ứng dụng của bạn có thể dẫn đến mã khó gỡ lỗi hoặc không an toàn.
this.GetName()
và sử dụng Phương thức hiện tạiMethodBase.GetCurrentMethod().Name
Tôi biết điều này đã cũ, nhưng cũng vậy, khi trong một bộ lọc như ActionFilter, bối cảnh không dễ dàng cung cấp cho bạn thông tin khu vực.
Nó có thể được tìm thấy trong mã sau đây:
var routeData = filterContext.RequestContext.RouteData;
if (routeData.DataTokens["area"] != null)
area = routeData.DataTokens["area"].ToString();
Vì vậy, bộ lọcContext đang được truyền vào phần ghi đè và RouteData chính xác được tìm thấy trong RequestContext. Có một RoutData ở cấp độ Cơ sở, nhưng DataTokens KHÔNG có khu vực trong từ điển của nó.
Tôi biết đây là một bài viết rất cũ nhưng chúng ta có thể sử dụng Thuộc tính giá trị giống hệt như DataTokens
Url.RequestContext.RouteData.Values ["action"] đã làm việc cho tôi.
Tôi không biết tại sao nhưng chấp nhận câu trả lời là không hoạt động. Nó trả về null với ví dụ (có thể về mvc, tôi sử dụng lõi .net)
Tôi luôn gỡ lỗi biến và tìm nạp dữ liệu từ đó.
Thử cái này. Nó làm việc cho tôi
var area = ViewContext.RouteData.Values["area"]
Ví dụ logic chi tiết
Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";