ASP.NET MVC보기에서 현재 작업을 어떻게 반환 할 수 있습니까?


291

현재 컨트롤러 및 작업에 따라 마스터 페이지에서 CSS 클래스를 설정하고 싶었습니다. 나는 통해 현재 컨트롤러에 얻을 수 ViewContext.Controller.GetType().Name있지만, 어떻게 (예를 들어, 현재 조치를받을 수 있나요 Index, Show등)?

답변:


83

사용 ViewContext상기와 모양을 RouteData컨트롤러와 액션 요소 모두를 추출하는 모음입니다. 그러나 컨트롤러 / 액션 대신 애플리케이션 컨텍스트 (예 : "editmode"또는 "error")를 나타내는 일부 데이터 변수를 설정하면 뷰와 컨트롤러 사이의 연결이 줄어 듭니다.


컨트롤러에서 데이터를 가져 와서 DTO에서 볼 수 있도록 전달할 수 있습니다. stackoverflow.com/a/31749391/4293929
MstfAsan

5
이것은 허용되는 답변이 아니어야합니다. 가장 많이 투표 된 답변을 참조하십시오.
Hakan Fıstık

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+ 변형입니다
Chris S

7
이 구문은 V4에서 작동합니다. (string) ViewContext.RouteData.Values ​​[ "action"];
kiprainey

2
이 솔루션은 저에게 효과적이지 않습니다 (MVC4 + .NET Framework 4.5.1). 저에게는 Viacheslav Smityukh의 답변이 있습니다 : ViewContext.RouteData.Values ​​[ "action"], ViewContext.RouteData.Values ​​[ "controller"], ViewContext.RouteData.Values ​​[ "id"],
Tomas Kubes

@kiprainey V3.5에서도 : msdn.microsoft.com/en-us/library/…
Pluto

2
시도 : (문자열) 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 ()에서 예외가 발생합니다
그리즐리 피크 소프트웨어

@ShaneLarson null과 비교하거나 ViewContext.RouteData.Values.ContainsKey(<key>)먼저 확인하십시오 .
Pluto

40

나는 이것이 오래된 질문이라는 것을 알고 있지만 그것을 보았고보기가 처리하는 데 필요한 데이터를 검색하도록하는 것보다 대체 버전에 관심이있을 것이라고 생각했습니다.

내 의견으로는 더 쉬운 방법은 OnActionExecuting 메서드 를 재정의하는 것입니다. 찾고있는 정보를 얻는 데 사용할 수 있는 ActionDescriptor 멤버 ( ActionName) 가 포함 된 ActionExecutingContext 가 전달되며 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

액션 담당자를 얻는 것이 내가 필요한 것입니다. 다른 솔루션을 찾을 수 없으므로 여기에서 수행 한 다음 viewbag에 원하는 것을 밀어 넣으십시오.
Chris Marisic

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

따라서 View (또는 master / layout)에서 다음과 같이 사용할 수 있습니다 (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>

도움이 되길 바랍니다.


15

ViewContext의 RouteData에서 이러한 데이터를 얻을 수 있습니다.

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

9

MVC에서는 View에 모든 데이터를 제공해야하며 View가 자체 데이터를 수집하지 않도록해야합니다. 컨트롤러 작업에서 CSS 클래스를 설정하는 것이 가능합니다.

ViewData["CssClass"] = "bold";

View의 ViewData에서이 값을 선택하십시오.


이것은 컨트롤러 구조에 따라 뷰를 유지하기 위해 선호하는 방법 일 수도 있지만 그렇지 않으면 수행 할 수 있습니다.
tvanfosson '12

1
디스플레이 로직이 컨트롤러에 들어온다는 것을 나타내는 것처럼 "CssClass"라는 이름으로 확실하지 않습니다.
tvanfosson '12

동의합니다. 일반적으로 "컨텍스트"와 같은 작업을 수행하므로 프레젠테이션 레이어에 연결되지 않으며 뷰의 이름을 바꾸어도 중단되지 않습니다.
RedFilter

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

데일 레이건의 답변 연장재사용을위한 그의 예인 하여 Controller에서 파생되는 ApplicationController 클래스를 만들고 다른 모든 컨트롤러가 Controller가 아닌 해당 ApplicationController 클래스에서 파생되도록합니다.

예:

public class MyCustomApplicationController : Controller {}

public class HomeController : MyCustomApplicationController {}

새 ApplicationController에서이 서명으로 ExecutingAction이라는 특성을 작성하십시오.

protected ActionDescriptor ExecutingAction { get; set; }

그런 다음 Dale Ragan의 답변에 따라 OnActionExecuting 메서드에서 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.