简体   繁体   English

MVC 4-通过ViewBag将数据传递到_Layout部分视图

[英]MVC 4 - pass data via ViewBag to _Layout partial view

I have a _Layout.cshtml files as a partial view as header on each main view. 我有一个_Layout.cshtml文件作为局部视图作为每个主视图上的标头。

I would like to define a Select element on the _Layout and pass some data to the partial view using ViewBag so that the data is populated on the view and can later be submitted. 我想在_Layout上定义一个Select元素,并使用ViewBag将一些数据传递到局部视图,以便该数据填充在该视图上并可以稍后提交。

My questions are: 我的问题是:

  • Where is the ActionResult function defined that contains and defines the data in ViewBag? 定义并包含ViewBag中数据的ActionResult函数在哪里?
  • What do I do if I want to submit a form on the partial view? 如果要在局部视图上提交表单,该怎么办? Where and which action should be defined/used to accept the HttpPost command? 应该在何处定义哪个动作/用于接受HttpPost命令?

Thanks! 谢谢!

What I suggest is to make a base controller class. 我建议做一个基本的控制器类。 Inherit all your controllers from it. 从那里继承所有控制器。 The code to render the data for the layout, can lie in it's constructor, or some other common function that all your controllers can use as children of this base class. 呈现布局数据的代码可以位于其构造函数中,也可以位于所有其他控制器可用作该基类的子代的某些其他常用函数中。

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

About your question: 关于您的问题:

What do I do if I want to submit a form on the partial view? 如果要在局部视图上提交表单,该怎么办? Where and which action should be defined/used to accept the HttpPost command? 应该在何处定义哪个动作/用于接受HttpPost命令?

You can just put the controller name on your form: 您可以将控制器名称放在表单上:

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

There are possibly a few misunderstandings about how _layout.cshmtl and partial views work: 关于_layout.cshmtl和部分视图的工作方式,可能会有一些误解:

  • _layout.cshtml is not a partial view. _layout.cshtml不是局部视图。 It is the layout template used by all your pages. 它是您所有页面使用的布局模板。 It is kind of the "outer" of the page. 这是页面的“外部”。 It is automatically applied (except if you set Layout = null ). 它会自动应用(除非您设置Layout = null )。 A partial view in turn is the "inner" of the page. 局部视图又是页面的“内部”。 You call it explicitly from your page using @Html.Partial . 您可以使用@Html.Partial从页面中显式调用它。

  • Even though your page is rendered by multiple views - the actual view, the layout, maybe some partial views - it is still the result of a single controller action. 即使您的页面是由多个视图(实际视图,布局,也许还有一些局部视图)呈现的,它仍然是单个控制器动作的结果。 (Except if you use @Html.Action for rendering partial "actions"). (除非您使用@Html.Action呈现部分“动作”)。 Also, the page rendered is a single HTML page, that is, any forms on the page are simply HTML forms. 同样,呈现的页面是单个HTML页面,也就是说,页面上的任何表单都只是HTML表单。

Therefore, the answer to "where is the ActionResult function defined" is: In the action that you want your page to be rendered for.* 因此,“ ActionResult函数定义在何处”的答案是:在您要为其呈现页面的操作中。*

The answer to "Which action should be used to accept the HttpPost command" is the same as if the form was on your page: You can define an arbitrary action on an arbitrary controller for receiving the form. 答案“应该使用哪个动作来接受HttpPost命令”与表单在页面上的方式相同:您可以在任意控制器上定义任意动作以接收表单。 You just need to refer to that action when you render the form: 呈现表单时,您只需要引用该操作即可:

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

*) If you want to prevent having to build the select list in each and every controller action that relies on _layout, you could conceivably use @Html.Action . *)如果您希望避免在每个依赖_layout的控制器操作中构建选择列表,可以想到使用@Html.Action That is, you define a "partial action" which is nothing else than a controller action that returns a PartialView() and a partial view to render the model from that action. 也就是说,您定义了一个“局部动作”,无非就是一个控制器动作,该动作返回一个PartialView()和一个局部视图以从该动作中渲染模型。 Then you can use that partial action to build the select list. 然后,您可以使用该部分操作来构建选择列表。

However having read some news about ASP.NET vNext, partial actions seem not to be liked to much by the community and in vNext there will be another way to achieve the same. 但是,在阅读了有关ASP.NET vNext的一些新闻后,社区似乎不太喜欢局部操作,在vNext中,将有另一种方法来实现这一点。

Still if you want to go this way this enables you to separate the logic for your dropdown (language? user menu?) from your other actions and views: 仍然,如果您要采用这种方式,则可以使下拉菜单(语言?用户菜单?)的逻辑与其他操作和视图分离:

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

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

In your _layout you call the partial action: 在_layout中,您调用部分操作:

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

And in the view for UserMenuDropdown you render the form: 并在UserMenuDropdown的视图中呈现表单:

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

This way your dropdown list becomes a "first class member", with its own controller action, main view, and model. 这样,您的下拉列表将成为具有自己的控制器操作,主视图和模型的“一流成员”。 You don't need a ViewBag for this, and you don't have to build the select list in each and every controller action. 您不需要为此使用ViewBag,也不必在每个控制器操作中都建立选择列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM