Nhận tên khu vực hiện tại trong chế độ xem hoặc điều khiển


126

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:


217

Từ MVC2 trở đi bạn có thể sử dụng ViewContext.RouteData.DataTokens["area"]


22
Nếu không ở trong một khu vực, ViewContext.RouteData.DataTokens ["area"] == null.
dùng202448

23
... và trong MVC5 :)
Stefan

4
Lol .. trò đùa là ở bạn @Dante ... công bằng mà nói nó được gọi ASP.NET Core 1.0thay vì MVC6.. :-)
Rosdi Kasim

FYI - đã tìm ra điều gì không ổn với ajax POST của tôi không hoạt động ... vui lòng kiểm tra các yêu cầu ajax của bạn có khu vực trong URL ... họ vẫn có thể tìm thấy !!! Chế độ xem, nhưng họ sẽ không duy trì khu vực ... nếu url bị thiếu khu vực khi yêu cầu được thực hiện.
Seabizkit

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

3
Đây là cách tốt nhất, phổ biến để lấy thông tin khu vực, nếu bạn không ở trong chế độ xem hoặc bộ điều khiển. Cảm ơn bạn đã đăng bài này!
bdrelling

19

Bạn có thể lấy nó từ bộ điều khiển bằng cách sử dụng:

ControllerContext.RouteData.DataTokens["area"]

@ user202338 Các khu vực được giới thiệu trong MVC2 vì vậy tôi sẽ nghi ngờ như vậy, nhưng tôi không chắc liệu họ có thay đổi cách họ đưa vào bộ sưu tập DataTokens hay không. Tôi thấy các bài viết như thế này: liên kết nói về việc sử dụng nó trong MVC2.
Matt Penner

10

Trong ASP.NET Core 1.0, giá trị được tìm thấy trong

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


Bạn có chắc không? Theo như tôi có thể nhớ nó đã hoạt động khi chúng tôi chạy ứng dụng của chúng tôi trên ASP.NET Core 2.0 và hiện vẫn đang hoạt động trong ASP.NET Core 2.1 (đã được thử nghiệm trước đây).
zerox981

Bạn đã đúng, không chỉ làm việc cho các Trang dao cạo (không có ViewContext - pageModel.RouteData.Values.TryGetValue("area", out object area)nên được sử dụng thay thế)
Roman Pokrovskij

9

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>

Vì một số lý do, tôi không thể tìm thấy areamã thông báo trong Valuesnhưng cần phải tìm trong DataTokens... không biết tại sao.
Syska

8

Tôi đã tạo một phương thức mở rộng để RouteDatatrả 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;
}

RouteDatacó sẵn trên cả hai ControllerContextViewContextnó 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.DataTokenslà null vì điều này luôn được khởi tạo bên trong.


3

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.


1
Có một phương pháp như thế cho bộ điều khiển? Tôi ghét sử dụng chuỗi ký tự vào một bộ sưu tập.
Erick T

để sử dụng bộ điều khiển this.GetName()và sử dụng Phương thức hiện tạiMethodBase.GetCurrentMethod().Name
Nerdroid

3

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ó.


2

Để có được tên khu vực trong dạng xem, trong ASP.NET Core MVC 2.1:

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

2

Nhận tên khu vực trong Chế độ xem (.NET Core 2.2):

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

0

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.


0

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)

http: // localhost: 5000 / Quản trị viên / Nhóm khách hàng

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";
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.