【问题标题】:MVC 4 - pass data via ViewBag to _Layout partial viewMVC 4 - 通过 ViewBag 将数据传递给 _Layout 部分视图
【发布时间】:2015-01-21 19:08:18
【问题描述】:

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

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

我的问题是:

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

谢谢!

【问题讨论】:

  • ViewBagControllerBase 的属性,因此它可用于所有控制器方法。您可以发布到任何控制器中的任何方法。
  • 但是设置数据到 ViewBag 的 ActionResult 应该在哪里定义呢? _Layout 视图没有 Index ActionResult...
  • 如果您的布局文件有,例如<div>@ViewBag.SomeProperty</div>,并且在返回使用该布局的视图的操作方法中,如果您添加ViewBag.SomeProperty = "Some value",那么“一些值”将显示在查看

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


【解决方案1】:

我的建议是创建一个基本控制器类。 继承你所有的控制器。 为布局呈现数据的代码可以位于它的构造函数中,也可以位于所有控制器都可以用作此基类的子级的其他一些常用函数中。

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")) 

【讨论】:

    【解决方案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,也不必在每个控制器操作中构建选择列表。

    【讨论】:

    • 很好的答案,但 Html.Partial 没有 Action 和 Controller 的重载。应该是 Html.Action。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多