ビューまたはコントローラーで現在のエリア名を取得


126

ビューまたはコントローラーで現在のエリア名をどのように取得しますか?

ViewContext.RouteData.Values["controller"]エリアのようなものはありますか?

回答:


217

MVC2以降から使用できます ViewContext.RouteData.DataTokens["area"]


22
エリアにない場合、ViewContext.RouteData.DataTokens ["area"] == null。
user202448 2010年

23
...そしてMVC5では:)
Stefan

4
Lol ..ジョークはあなたにあります@Dante ...公平に言うASP.NET Core 1.0MVC6.. :-)の代わりに呼び出されます
Rosdi Kasim

参考までに-私のajax POSTの何が問題であるかを理解しました... ur ajaxリクエストにURL内の領域があることを確認してください...彼らはまだ見つけるかもしれません!!! ビュー、しかしそれらはエリアを維持しません...リクエストが行われたときにURLがエリアを欠いている場合。
Seabizkit 2018

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

3
これは、ビューまたはコントローラー内にいない場合に、エリア情報を取得するための最良の普遍的な方法です。これを投稿してくれてありがとう!
2013年

19

あなたはそれを使ってコントローラからそれを得ることができます:

ControllerContext.RouteData.DataTokens["area"]

@ user202338エリアはMVC2で導入されたので、疑わしいと思いますが、DataTokensコレクションへの入力方法が変更されたかどうかはわかりません。私はこのような投稿を見ます: MVC2でそれを使うことについて話すリンク
Matt Penner、2011

10

ASP.NET Core 1.0では、この値は

ViewContext.RouteData.Values ["area"];


本気ですか?私が覚えている限りでは、ASP.NET Core 2.0でアプリを実行したときに機能し、現在ASP.NET Core 2.1(テスト済み)でまだ機能しています。
zerox981 2018年

あなたは正しい、Razorページだけでは機能しない(ViewContextがない- pageModel.RouteData.Values.TryGetValue("area", out object area)代わりに使用する必要がある)
Roman Pokrovskij

9

これについて ab ログエントリを書いたところです。詳細については、そのログにアクセスしてください。しかし、私の答えは、以下に示す拡張メソッドを作成することでした。

重要な点は、MVCエリアを.DataTokensからプルし、コントローラー/アクションをRouteDataの.Valuesからプルすることでした。

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;
    }

次に、以下のように実装できます。

<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トークンをで見つけることができませんが、Valuesを調べる必要がありましたDataTokens...理由がわかりません。
Syska 2014年

8

RouteData現在のエリア名を返すための拡張メソッドを作成しました。

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

    return null;
}

とのRouteData両方ControllerContextで利用できるのでViewContextそれはあなたのコントローラとビューにアクセスすることができます。

テストも非常に簡単です。

[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.DataTokens常に内部で初期化されるため、null かどうかを確認する必要はありません。


3

MVC FuturesにはAreaHelpers.GetAreaName()メソッドがあります。ただし、この方法を使用する場合は注意してください。現在の領域を使用してアプリケーションに関する実行時の決定を行うと、デバッグが難しいコードや安全でないコードにつながる可能性があります。


1
コントローラにそのような方法はありますか?文字列リテラルをコレクションに使用するのは嫌いです。
エリックT

コントローラー用this.GetName()および現在のメソッド用MethodBase.GetCurrentMethod().Name
Nerdroid、2015

3

私はこれが古いことを知っていますが、ActionFilterのようなフィルターでは、コンテキストがエリア情報を簡単に提供しません。

次のコードにあります。

var routeData = filterContext.RequestContext.RouteData;

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

したがって、filterContextはオーバーライドで渡され、正しいRouteDataはRequestContextの下にあります。ベースレベルにはRoutDataがありますが、DataTokenにはディクショナリに領域がありません。



2

ビューで領域名を取得(.NET Core 2.2):

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

0

これは非常に古い投稿ですが、DataTokensとまったく同じ方法でValuesプロパティを使用できます。

Url.RequestContext.RouteData.Values ["action"]がうまくいきました。


0

理由はわかりませんが、受け入れられた回答が機能しません。例:nullを返します(おそらくmvcについて、.netコアを使用します)

http:// localhost:5000 / Admin / CustomerGroup

私は常に変数をデバッグし、その中からデータをフェッチします。

これを試して。わたしにはできる

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

詳細な論理例

Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.