32

I am confused with this: I have an action ,say Parent ,and in the corresponding view file ,I have called a child action ,say Child ,both Parent and Child actions are in the same controller.

and I need the Child action and the Parent action to share some data in the ViewBag.Now ,what I should do ?Here is my question:

when I call the Child action in parent's view file ,I pass the viewbag to it like this: @Html.Action(ViewBag). in my child action ,I do this:

public PartialViewResult Child(Object ViewBag)
{
  //using the data in ViewBag
}

Is this the right way ? Does the viewbag object passed by reference or it is a different object then the original viewbag(more memory needed)?

Or if the Child action is sharing the viewbag with its calling parent Action by default?

From Darin Dimitrov's answer ,I knew that I can't do something like this:@Html.Action(ViewBag)

But I really need to pass the child action muti-parameters,what can I do ?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
NextStep
  • 1,035
  • 3
  • 14
  • 18
  • 3
    Please don't prefix your questions with things like "[.NET MVC3]". On [so], we use tags for that purpose. – John Saunders Oct 12 '11 at 11:30
  • You might want to consider Html.Partial instead if your child action isn't completely separate from the parent – Bochu Oct 21 '16 at 14:34

2 Answers2

42

Child actions follow a different controller/model/view lifecycle than parent actions. As a result they do not share ViewData/ViewBag. If you want to pass parameters to a child action from the parent you could do this:

@Html.Action("Child", new { message = ViewBag.Message })

and in the child action:

public ActionResult Child(string message)
{
    ...
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 1
    Thank you for your answer ,but what if I want to pass the child action more than one message(parameter)?Thank you again:) – NextStep Oct 12 '11 at 10:50
  • 1
    Can't you just send it, for example, `new {message = ViewBag.Message, param2 = somethingElse}`? – John Saunders Oct 12 '11 at 11:32
  • Sorry ,but I need to pass the child action the flowing things : an ID (int) ,a message(string) ,and an object (my custom object), so ,I guess I am totally wrong to think about use this approach ?There's now way to pass a child action so many things at the same time ?:) – NextStep Oct 12 '11 at 11:52
  • Actually I can use an ID to get everything in the child action ,but the object is get from the database ,so I think its more expensive to search from the database than to pass to a child action :)If there is no way to pass ,I have to do the database search in the child action :) – NextStep Oct 12 '11 at 12:09
  • what about using `TempData[SomeId] = whatEverInstance` - isn't that the correct way of doing such things in MVC? – Lukas K Feb 04 '21 at 10:19
14

There is a way, but you have to create a custom abstract class as the base class for your razor views. Then expose whatever you need to from parent to child actions. This is how I get the root controller's ViewBag inside a class inheriting from WebViewPage

    private dynamic GetPageViewBag()
    {
        if (Html == null || Html.ViewContext == null) //this means that the page is root or parial view
        {
            return ViewBag;
        }
        ControllerBase controller = Html.ViewContext.Controller;

        while (controller.ControllerContext.IsChildAction)  //traverse hierachy to get root controller
        {
            controller = controller.ControllerContext.ParentActionViewContext.Controller;
        }
        return controller.ViewBag;
    }
mitsbits
  • 325
  • 3
  • 8
  • 1
    In my Child action, I am just calling `ViewBag.Variable = ControllerContext.ParentActionViewContext.ViewBag.Variable`. There's probably a way to loop through and get all the variables copied, but I just needed one. Thanks for the starting point. – bradlis7 Jan 15 '16 at 16:30
  • Try casting you viewbag to Dictionary if you want to loop. – mitsbits Jan 16 '16 at 14:49