2011-10-17 74 views
2

为了在MVC 3 Razor中渲染我的菜单我在主控制器中有一个菜单动作:public ActionResult Menu(){...} 这个动作获取菜单项并使用视图渲染它们。在_Layout中我使用:@ Html.Action(“Menu”,“Home”)来渲染菜单。这工作正常。MVC 3渲染菜单

我的问题是,我想选择当前项目。为此,呈现菜单中项目的每个操作都将添加到ViewBag中所选菜单项。问题是菜单操作中的ViewBag是空的。 这是正确的方法吗?我想要使​​用控制器呈现菜单+不仅查看视图。我想要这样做是为了避免在视图代码中使用逻辑代码并能够对其进行测试。

你知道更好的方法吗?

如何将数据从_Layout.cshtml传递到使用@ html.Action呈现的操作?

回答

1

尝试查看动作方法内部的RouteDataViewContext如果在构建菜单时使用HtmlHelper扩展名。拉出哪个是当前控制器,哪个是当前操作并相应地设置该菜单项。

从操作方法:

object controller = RouteData.Values["controller"]; 
object action = RouteData.Values["action"]; 
object area = RouteData.DataTokens["area"]; 

从HTML帮助:

object controller = helper.ViewContext.RouteData.Values["controller"]; 
object action = helper.ViewContext.RouteData.Values["action"]; 
object area = helper.ViewContext.RouteData.DataTokens["area"]; 
+0

这种方法不起作用。控制器是“家”,行动是“菜单”...它看起来像Html.Action覆盖路线数据项目 –

+1

我想不出你需要从一个行动方法调用此的原因。为什么不使用RenderPartial并将其连线或传入模型对象? – hunter

1

你可以把它作为参数:

@Html.Action("Menu", "Home", new { sleectedItem = (string)ViewBag.SomeItem }) 

,然后在子控制器动作使用这样的:

public ActionResult Menu(string selectedItem) 
{ 
    ... 
} 

,或者如果你需要的是获取当前控制器和动作,你可以简单地从的RouteData获取此信息,并摆脱任何ViewBag的:

public ActionResult Menu() 
{ 
    var rd = ControllerContext.ParentActionViewContext.RouteData; 
    var action = rd.GetRequiredString("action"); 
    var controller = rd.GetRequiredString("controller"); 

    // Now that you know the action and the controller build up your view model 
    // and pass to the view. It will then know which menu item to preselect 
    ... 
}