ASP.NET MVCビューで現在のアクションを返すにはどうすればよいですか?


291

現在のコントローラーとアクションに応じて、マスターページにCSSクラスを設定したいと思いました。私は、を介して電流コントローラに取得することができViewContext.Controller.GetType().Nameますが、どのように私は(例えば、現在のアクションを取得しないIndexShowなど)?

回答:


83

を使用ViewContextしてRouteDataコレクションを確認し、コントローラー要素とアクション要素の両方を抽出します。ただし、コントローラー/アクションではなく、アプリケーションコンテキストを示すデータ変数(「editmode」や「error」など)を設定すると、ビューとコントローラー間の結合が減少すると思います。


コントローラでデータを取得し、DTOで表示するために渡すことができます。stackoverflow.com/a/31749391/4293929
MstfAsan 2015

5
これは受け入れられた回答であってはなりません。代わりに最も投票された回答を参照してください。
HakanFıstık16年

1
@HakamFostokモデルにセマンティック情報を追加するアドバイスは、他の回答がそのデータを取得する方法の詳細を提供している場合でも、ビューでルートデータ(コントローラー、アクション)に依存するよりも、すべての場合に優れた方法であるとまだ思います。
tvanfosson

467

RCでは、このようなアクションメソッド名のようなルートデータを抽出することもできます

ViewContext.Controller.ValueProvider["action"].RawValue
ViewContext.Controller.ValueProvider["controller"].RawValue
ViewContext.Controller.ValueProvider["id"].RawValue

MVC 3の更新

ViewContext.Controller.ValueProvider.GetValue("action").RawValue
ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
ViewContext.Controller.ValueProvider.GetValue("id").RawValue

MVC 4の更新

ViewContext.Controller.RouteData.Values["action"]
ViewContext.Controller.RouteData.Values["controller"]
ViewContext.Controller.RouteData.Values["id"]

MVC 4.5の更新

ViewContext.RouteData.Values["action"]
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["id"]

20
私はこの前の日付にV2を知っているが、それは今だViewContext.Controller.ValueProvider.GetValue("action").RawValue+バリエーション
クリス・S

7
この構文はV4で機能します。(string)ViewContext.RouteData.Values ["action"];
kiprainey 2013

2
このソリューションは私には機能しません(MVC4 + .NET Framework 4.5.1)。私にとっては、Viacheslav Smityukhからの答えが機能します。ViewContext.RouteData.Values["action"]、ViewContext.RouteData.Values ["controller"]、ViewContext.RouteData.Values ["id"]、
Tomas Kubes

あまりにV3.5では@kiprainey:msdn.microsoft.com/en-us/library/...
冥王星

2
試してください:(string)HttpContext.Request.RequestContext.RouteData.Values ["action"];
Martin Dawson

60

ビューの現在のIDを取得するには:

ViewContext.RouteData.Values["id"].ToString()

現在のコントローラーを取得するには:

ViewContext.RouteData.Values["controller"].ToString() 

1
RouteContextに値が存在しない場合、ViewContext.RouteData.Values [<key>]。ToString()が例外をスローします
Grizzly Peak Software

@ShaneLarson nullと比較するか、ViewContext.RouteData.Values.ContainsKey(<key>)最初に確認します。
プルート

40

私はこれが古い質問であることを知っていますが、私はそれを見て、あなたがあなたのビューにそれが仕事をするのに必要なデータを検索することを許可させるよりも別のバージョンに興味があるかもしれないと思いました。

私の意見では、より簡単な方法は、OnActionExecutingメソッドをオーバーライドすることです。必要な情報を取得するために使用できるActionDescriptorメンバーを含むActionExecutingContextが渡されます。これはActionNameであり、ControllerDescriptorに到達することもでき、ControllerNameが含まれています。

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    ActionDescriptor actionDescriptor = filterContext.ActionDescriptor;
    string actionName = actionDescriptor.ActionName;
    string controllerName = actionDescriptor.ControllerDescriptor.ControllerName;
    // Now that you have the values, set them somewhere and pass them down with your ViewModel
    // This will keep your view cleaner and the controller will take care of everything that the view needs to do it's job.
}

お役に立てれば。どちらかといえば、少なくともそれはあなたの質問によって来る他の誰かのための代替案を示します。


素敵な推薦; コントローラ/アクションセンシングをインテリジェントに実装するのに役立ちました。ありがとう!
effkay、2009

アクション記述子を取得することが私が必要とするものであり、他のソリューションを見つけることができなかったので、ここでそれを実行し、必要なものをビューバッグに押し込みます。
Chris Marisic 2012年

17

私はさまざまな答えを見て、クラスヘルパーを思いつきました。

using System;
using System.Web.Mvc;

namespace MyMvcApp.Helpers {
    public class LocationHelper {
        public static bool IsCurrentControllerAndAction(string controllerName, string actionName, ViewContext viewContext) {
            bool result = false;
            string normalizedControllerName = controllerName.EndsWith("Controller") ? controllerName : String.Format("{0}Controller", controllerName);

            if(viewContext == null) return false;
            if(String.IsNullOrEmpty(actionName)) return false;

            if (viewContext.Controller.GetType().Name.Equals(normalizedControllerName, StringComparison.InvariantCultureIgnoreCase) &&
                viewContext.Controller.ValueProvider.GetValue("action").AttemptedValue.Equals(actionName, StringComparison.InvariantCultureIgnoreCase)) {
                result = true;
            }

            return result;
        }
    }
}

ビュー(またはマスター/レイアウト)では、次のように使用できます(Razor構文)。

            <div id="menucontainer">

                <ul id="menu">
                    <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("home", "index", ViewContext)) {
                            @:class="selected"
                        }>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("account","logon", ViewContext)) {
                            @:class="selected"
                        }>@Html.ActionLink("Logon", "Logon", "Account")</li>
                    <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("home","about", ViewContext)) {
                            @:class="selected"
                        }>@Html.ActionLink("About", "About", "Home")</li>
                </ul>

            </div>

それが役に立てば幸い。



9

MVCでは、ビューにすべてのデータを提供する必要があります。ビューに独自のデータを収集させないでください。そのため、コントローラーアクションでCSSクラスを設定することができます。

ViewData["CssClass"] = "bold";

そして、ビューのViewDataからこの値を選びます


これは、ビューがコントローラーの構造に依存しないようにするための私の推奨方法でもありますが、それ以外の場合も可能です。
tvanfosson 2008

1
表示ロジックがコントローラーに忍び込んでいることを示しているように見えるので、「CssClass」という名前を付けるかどうかはわかりません。
tvanfosson 2008

確かに、私は通常「コンテキスト」のようなことをするので、プレゼンテーションレイヤーに関連付けられておらず、ビューの名前を変更しても壊れません。
RedFilter 2008

6

私はこれに投票します2:

string currentActionName = ViewContext.RouteData.GetRequiredString("action");

そして

string currentViewName = ((WebFormView)ViewContext.View).ViewPath;

現在のビューの物理名とそれをトリガーしたアクションの両方を取得できます。ホストコンテナーを決定するために、部分的な* .acmxページで役立ちます。


2

私はASP.NET MVC 4を使用していますが、これは私にとってうまくいきました:

ControllerContext.Controller.ValueProvider.GetValue("controller").RawValue
ControllerContext.Controller.ValueProvider.GetValue("action").RawValue

0

Dale Raganの回答(彼の再利用の例)を拡張して、Controllerから派生するApplicationControllerクラスを作成し、他のすべてのコントローラーをControllerではなくそのApplicationControllerクラスから派生させます。

例:

public class MyCustomApplicationController : Controller {}

public class HomeController : MyCustomApplicationController {}

新しいApplicationControllerで、次のシグネチャを持つExecutingActionという名前のプロパティを作成します。

protected ActionDescriptor ExecutingAction { get; set; }

次に、OnActionExecutingメソッド(Dale Raganの回答から)で、このプロパティにActionDescriptorを割り当てるだけで、任意のコントローラーで必要なときにいつでもアクセスできます。

string currentActionName = this.ExecutingAction.ActionName;

0

コントローラでこの関数をオーバーライドします

protected override void HandleUnknownAction(string actionName) 
{  TempData["actionName"] = actionName;
   View("urViewName").ExecuteResult(this.ControllerContext);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.