ฉันต้องการตั้งคลาส CSS ในหน้าต้นแบบของฉันซึ่งขึ้นอยู่กับตัวควบคุมและการกระทำในปัจจุบัน ฉันจะได้รับไปยังตัวควบคุมปัจจุบันผ่านViewContext.Controller.GetType().Name
แต่ฉันจะได้รับการดำเนินการปัจจุบัน (เช่นIndex
, Show
ฯลฯ )?
ฉันต้องการตั้งคลาส CSS ในหน้าต้นแบบของฉันซึ่งขึ้นอยู่กับตัวควบคุมและการกระทำในปัจจุบัน ฉันจะได้รับไปยังตัวควบคุมปัจจุบันผ่านViewContext.Controller.GetType().Name
แต่ฉันจะได้รับการดำเนินการปัจจุบัน (เช่นIndex
, Show
ฯลฯ )?
คำตอบ:
ใช้ViewContext
และดูที่RouteData
คอลเล็กชันเพื่อแยกทั้งองค์ประกอบคอนโทรลเลอร์และแอ็คชัน แต่ฉันคิดว่าการตั้งค่าตัวแปรข้อมูลบางอย่างที่บ่งบอกถึงบริบทของแอปพลิเคชัน (เช่น "editmode" หรือ "ข้อผิดพลาด") แทนที่จะควบคุม / การกระทำลดข้อต่อระหว่างมุมมองและตัวควบคุมของคุณ
ใน RC คุณสามารถดึงข้อมูลเส้นทางเช่นชื่อวิธีการกระทำเช่นนี้ได้
ViewContext.Controller.ValueProvider["action"].RawValue
ViewContext.Controller.ValueProvider["controller"].RawValue
ViewContext.Controller.ValueProvider["id"].RawValue
ViewContext.Controller.ValueProvider.GetValue("action").RawValue
ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
ViewContext.Controller.ValueProvider.GetValue("id").RawValue
ViewContext.Controller.RouteData.Values["action"]
ViewContext.Controller.RouteData.Values["controller"]
ViewContext.Controller.RouteData.Values["id"]
ViewContext.RouteData.Values["action"]
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["id"]
ViewContext.Controller.ValueProvider.GetValue("action").RawValue
+ การเปลี่ยนแปลง
วิธีรับรหัสปัจจุบันบนมุมมอง:
ViewContext.RouteData.Values["id"].ToString()
ในการรับคอนโทรลเลอร์ปัจจุบัน:
ViewContext.RouteData.Values["controller"].ToString()
ViewContext.RouteData.Values.ContainsKey(<key>)
ก่อน
ฉันรู้ว่านี่เป็นคำถามที่เก่ากว่า แต่ฉันเห็นและฉันคิดว่าคุณอาจสนใจรุ่นอื่นแทนที่จะปล่อยให้มุมมองของคุณจัดการกับการดึงข้อมูลที่ต้องใช้เพื่อทำงาน
วิธีที่ง่ายกว่าในความคิดของฉันคือการแทนที่วิธีOnActionExecuting คุณถูกส่งผ่านActionExecutingContextที่ประกอบด้วยสมาชิกActionDescriptorซึ่งคุณสามารถใช้เพื่อรับข้อมูลที่คุณกำลังค้นหาซึ่งเป็น 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.
}
หวังว่านี่จะช่วยได้ หากมีอะไรอย่างน้อยก็จะแสดงทางเลือกให้กับคนอื่นที่มาจากคำถามของคุณ
ฉันเห็นคำตอบที่แตกต่างและเกิดขึ้นกับผู้ช่วยในชั้นเรียน:
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) คุณสามารถใช้มันได้ (ไวยากรณ์ของมีดโกนหนวด):
<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>
หวังว่ามันจะช่วย
คุณสามารถรับข้อมูลเหล่านี้ได้จาก RouteData ของ ViewContext
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]
ใน MVC คุณควรจัดเตรียมมุมมองพร้อมข้อมูลทั้งหมดอย่าปล่อยให้มุมมองรวบรวมข้อมูลของตัวเองเพื่อที่คุณสามารถทำได้คือตั้งค่าคลาส CSS ในแอคชั่นควบคุมของคุณ
ViewData["CssClass"] = "bold";
และเลือกค่านี้จาก ViewData ของคุณในมุมมองของคุณ
ฉันลงคะแนนให้ 2:
string currentActionName = ViewContext.RouteData.GetRequiredString("action");
และ
string currentViewName = ((WebFormView)ViewContext.View).ViewPath;
คุณสามารถเรียกคืนทั้งชื่อฟิสิคัลของมุมมองปัจจุบันและแอ็คชันที่เรียกใช้ มันสามารถเป็นประโยชน์ในหน้า * .acmx บางส่วนเพื่อกำหนดโฮสต์คอนเทนเนอร์
ฉันกำลังใช้ ASP.NET MVC 4 และสิ่งนี้ใช้ได้กับฉัน:
ControllerContext.Controller.ValueProvider.GetValue("controller").RawValue
ControllerContext.Controller.ValueProvider.GetValue("action").RawValue
ขยายคำตอบของ Dale Raganตัวอย่างของเขาสำหรับการนำมาใช้ใหม่สร้างคลาส ApplicationController ซึ่งมาจากตัวควบคุมและในทางกลับกันให้คอนโทรลเลอร์อื่น ๆ ของคุณได้รับมาจากคลาส 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;
แทนที่ฟังก์ชั่นนี้ในคอนโทรลเลอร์ของคุณ
protected override void HandleUnknownAction(string actionName)
{ TempData["actionName"] = actionName;
View("urViewName").ExecuteResult(this.ControllerContext);
}