0

Basically I have a webpage structure where common parts of the page (header, side bar, etc) are generated in a separate controller filled with child actions outputting partial views. I then call these actions (using RenderAction()) from the layout page of the website.

So (if I'm right in saying this), There are multiple internal mvc pipelines (header/sidebar internal requests) including the original request pipeline to for the specific webpage. How/Where can I initialize some data from the original pipeline request and have that data accessible from the other internal mvc pipeline requests?

Summary of what I want to accomplish (with example)

  1. Request for website comes in.
  2. MVC starts pipeline for "Home" controller, "index" action.
  3. Before the Action gets executed, some data needs to be created that can later be accessible.
  4. From the layout page, several "RenderAction" Methods get executed creating sub pipelines for interal requests (e.g. "Shell" controller, "DisplayHeaderBar" action
  5. "DisplayHeaderBar" needs to access some data that was set in step 3 before rendering partial view

Hopefully this makes sense...

ekad
  • 14,436
  • 26
  • 44
  • 46
Josh
  • 23
  • 3
  • I would store the data created in step 3 in the model for the "Home" Page, then pass the data from the model to the partial view. Think of display header bar as a sub pipeline that gets rendered server side sure but it gets rendered after the main pipeline – theDarse Feb 20 '15 at 13:26
  • Partial view is not within the "Home" page. Partial views (for header/side bar) rendered in_Layout.cshtml. For Exmaple, in layout.... @{Html.RenderAction("DisplayHeaderBar");} @RenderBody() – Josh Feb 20 '15 at 14:38
  • Create a viewModel for the whole page. Where you call RenderAction, pass data from main viewModel to child action in @Html.RenderAction. Then in child controller action, access that data and consume it. – tranceporter Feb 20 '15 at 15:03

2 Answers2

0

What you're looking for are child actions. You simply create an action in some controller that returns a partial view. For example, you could handle your site navigation via:

[ChildActionOnly]
public ActionResult SiteNavigation()
{
    // get the data for your nav
    return PartialView("_SiteNavigation", yourSiteNavModel);
}

The ChildActionOnly attribute ensures that this action can only be called as a child action, making it inaccessible via typing a URL in a browser's navigation bar.

Then, you create a view in Views\Shared\_SiteNavigation.cshtml:

@model Namespace.To.ClassForSiteNavigation

<!-- render your site navigation using the model -->

Finally, in your layout:

@Html.Action("SiteNavigation", "ControllerWhereThisExists")
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
-2

I think you could use Tempdata for that. Tempdate gets deleted after you access it, so if you want to use the data more then once use Tempdata.Peek or Tempdata.Keep.

Here is a link with some explanation how you can pass data in asp.net mvc.

https://msdn.microsoft.com/en-us/library/dd394711%28v=vs.100%29.aspx

If tempdata doesn't do it then you could use cache.

okisinch
  • 96
  • 4
  • No. Full stop. Do not use `TempData` for this. Period. – Chris Pratt Feb 20 '15 at 14:04
  • the problem here is while theoretically temp data works for this it destroys the browsers ability to navigate with the back button since there is nothing in temp data, and a null reference exception will be thrown if you try to navigate back to this page – theDarse Feb 20 '15 at 21:24
  • @theDarse Tempdata is deleted when read, but you can use keep and peek to read it and still have it for later. http://stackoverflow.com/questions/21252888/tempdata-keep-vs-peek. Anyway I think it could work, maybe I didn't understand the problem well. – okisinch Feb 23 '15 at 11:58