MVC 4 - 通过ViewBag将数据传递给_Layout局部视图

时间:2014-11-24 05:51:20

标签: asp.net asp.net-mvc asp.net-mvc-4

我将_Layout.cshtml文件作为部分视图作为每个主视图上的标题。

我想在_Layout上定义一个Select元素,并使用ViewBag将一些数据传递给局部视图,以便在视图中填充数据,以后可以提交。

我的问题是:

  • 定义了哪些ActionResult函数包含并定义ViewBag中的数据?
  • 如果我想在局部视图上提交表单,该怎么办?应该在哪里和哪个动作定义/用于接受HttpPost命令?

谢谢!

2 个答案:

答案 0 :(得分:3)

我建议做一个基本控制器类。 从中继承所有控制器。 为布局呈现数据的代码可以在其构造函数中,或者所有控制器可以用作此基类的子代的一些其他常用函数。

public class BaseController : System.Web.Mvc.Controller 
{
   public BaseController()
   {
     // This code will run for all your controllers
     ViewBag.MyData = "SomeData";
   }
}

关于您的问题:

  

如果我想在局部视图上提交表单,该怎么办?应该在哪里和哪个动作接受HttpPost命令?

您可以将控制器名称放在表单上:

@using (Html.BeginForm("ActionName", "Controller")) 

答案 1 :(得分:2)

关于_layout.cshmtl和部分视图如何工作可能存在一些误解:

  • _layout.cshtml不是局部视图。它是您所有页面使用的布局模板。它是页面的“外部”。它会自动应用(除非您设置Layout = null)。部分视图反过来是页面的“内部”。您可以使用@Html.Partial从您的网页明确调用它。

  • 即使您的页面由多个视图呈现 - 实际视图,布局,也许是一些部分视图 - 它仍然是单个控制器操作的结果。 (除非您使用@Html.Action呈现部分“操作”)。此外,呈现的页面是单个HTML页面,也就是说,页面上的任何表单都只是HTML表单。

因此,“ActionResult函数定义在哪里”的答案是:在您希望渲染页面的操作中。*

“应该使用哪个操作来接受HttpPost命令”的答案与页面上的表单相同:您可以在任意控制器上定义任意操作以接收表单。您只需在渲染表单时引用该操作:

@using (Html.BeginForm("action", "controller")) { ... }

*)如果您想要防止必须在依赖于_layout的每个控制器操作中构建选择列表,您可以想象使用@Html.Action。也就是说,您定义一个“部分操作”,它只是一个返回PartialView()的控制器操作,而是一个部分视图,用于从该操作中呈现模型。然后,您可以使用该部分操作来构建选择列表。

然而,在阅读了有关ASP.NET vNext的一些新闻之后,社区似乎并不喜欢部分操作,而在vNext中,还有另一种方法可以实现相同的目标。

如果您想这样做,这可以让您将下拉菜单(语言?用户菜单?)与其他操作和视图分开:

class UserController
{
    PartialViewResult UserMenuDropdown()
    {
        return PartialView(BuildUserMenuFrom(.....));
    }

    [Post]
    ActionResult PostUserMenu()
    {
        // do whatever you want once the form is posted
    }
}

在_layout中,您可以调用部分操作:

@Html.Action("UserMenuDropdown", "User")

在UserMenuDropdown的视图中,您将呈现表单:

@using (Html.BeginForm("PostUserMenu"))
{
    @Html.DropDownListFor(m => m.UserMenuSelectList)
}

这样,您的下拉列表将成为“第一类成员”,具有自己的控制器操作,主视图和模型。您不需要ViewBag,也不必在每个控制器操作中构建选择列表。