I'm trying to share data from my main _Layout to the views rendered by RenderBody.
I tried to use a ViewBag initialized in "Shared/_Layout" but it doesn't work. However, I noticed that this ViewBag can be used in partials but not in the views displayed by #RenderBody.
Example _Layout:
PageData["XX"] = "myValue";
ViewContext.Controller.ViewBag.XX= "myValue";
Page.XX= "myValue";
ViewBag.XX= "myValue";
ViewContext.ViewData["XX"] = "myValue";
<body>
#Html.Partial("_MyPartial") // Everything has the correct value in the partial
<main class="content">
#RenderBody() // Everything is null in that view
</main>
</body>
I tried with ViewBag.Property, ViewData["Property"], Page.Property and PageData["Property"] but they are all null in the view rendered by RenderBody.
It seems that because the Layout is the last element compiled.
I don't want to use any code. Everything needs to be in the view, do something pretty similar to my example above. It must be in the layout because the value I want to share is defined by the user through the CMS. It means that this layout is used by static page but also views rendered by controller.
My question is: How I can give/share data from the _Layout to my views rendered by RenderBody()?
try this in your Layout :
#ViewContext.Controller.ViewBag.Test= "test";
How I can give/share data to my views rendered by RenderBody()?
Controllers are responsible for preparing the data (model, ViewBag, TempData, etc) and handing it over to Views.
You could also look into filters for preparing the data.
You need to populate your ViewBag in your Controller:
public class HomeController
{
public ActionResult Index()
{
// populate your ViewBag
ViewBag.myValue = "some text";
}
}
And then in your View/PartialView you can use it like this:
MyPartialView.cshtml
<label>#ViewBag.myValue</label>
Yes you can used viewBag in your partials view. When call viewBag in razor file(.cshtml)
you must be return a partial view for display.
ViewBag and ViewData is view-specific, so they're emptied whenever you hit a different View/Action. Try checking this link http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications for more info.
Try using TempData for that effect - http://www.tutorialsteacher.com/mvc/tempdata-in-asp.net-mvc
Related
I have an entire Web Application built using ASP.NET MVC and have a _ViewStart.cshtml page that specifies a Layout.
This works great for my entire site. However, I have a single prototype static HTML page that I just need to dump into a directory.
I copied the HTML into a CSHTML file and fronted it with a controller. The problem is that when I go to this page, it is using the Layout.
How can I configure it so that I can just serve this page up as static, standalone content without the Layout from _ViewStart?
By default, all views will use the layout from ~/Views/Shared as it is specified in the _Viewstart.cshtml file. Every time a view is executed, the code inside the _Viewstart.cshtml will be executed which sets the layout for the view.
If you do not want to execute/include the layout for a specific view, you can explicitly set layout as null on a view. Add the below code to the view.
#{
Layout = null;
}
Keep in mind that, even though it is static html in your cshtml file, user will not/should not directly access this view (like a normal html page/htm page). It has to be routed via an action method which returns this cshtml view.
Another option is to use the PartialView method instead of View method. When using the PartialView method to render a view, the framework do not run _ViewStart.cshtml, hence you get the same result.
public ActionResult About()
{
return PartialView();
}
PartialView is really handy when you want to render the markup for parts of your page (Ex : content of for a modal dialog etc)
In your static view page set layout = null.
Like:
#{Layout = null;}
How do I render a full fledged view (not partial view) inside another view?
Scenario, I have different controller and want the exactly same view to render which is already there under other controller with different layout.
I have Wishlist page in Home Controller which shows list of added products, and when user logged in , when I click on wish list it also show me navigation when user is signed in.
How would I do that??
Not many developers know about this but you can use RenderPage, it's specifically designed for that purpose(to render an MVC view inside another view)
#RenderPage("~/Views/Shared/SampleView.cshtml")
You can still create or use a partial view with its own controller and use the RenderAction()
[ChildActionOnly]
public ActionResult ActionPartialView(string p1)
{
//code...
return PartialView();
}
The above code can be in any controller, its own controller, just call it in razor with that controller.
Razor:
#{ Html.RenderAction("Index", "Home"); }
Hope that helps
I am Working On MVC4 architecture. I have a default layout i.e _Layout and models and view associated with it. It's Working fine.
Now Due to Some Requirement, after i Click on specific link i need it to redirect it a Whole different Layout and there i will associate models and view according to my Need.
But How to add a new layout and also keep the existing default layout in place.
For ex :- On Index page i gave a link Nikhil</a> -->. When i click this i have to go to a seperate layout and view.
Please Help in simplest and descriptive way possible because i am new to MVC4.
Thanks In Advance.
Yes, you can create multiple layout for different views if you want. In my case I have AdminLayout and UserLayout in my Shared folder. Just replace Layout variable.
Ex.
// For Admin Pages
#{
Layout = "~/Views/Shared/AdminLayout.cshtml";
}
//For User Pages
#{
Layout = "~/Views/Shared/UserLayout.cshtml";
}
By the way I use razor view engine here.
For Navigation you can create an ActionLink using HTML Heplers on your index page Like:
#Html.ActionLink("Link Text", "Controller","Action")
Now when you click on this link , the action specified of the controller will be accessed and in the action you can return the desired view, which has the different layout like :
public ActionResult Login()
{
return View("Desired View Name");
}
I have an Action result that returns a list
public ActionResult GetData(Profiles profiles)
{
Vertical Vdata = new Vertical();
List<Ver> Vertical = new List<Ver>();
//Code to fill list
return View(Vertical);
}
And then a partial view to display the List
#model IEnumerable< List<VerticalContainer.Models.Vertical>>
#foreach(var item in Model)
{
<span>#item.name</span>
}
I'm not sure how to render the partial view from my main view
#Html.Action("GetData")??
What do I pass with the Html.Action? or Should I use Partial/RenderPartial?
1- the correct way to render actions is as per the following:
#Html.RenderAction("ACTION_NAME","CONTROLLER_NAME")
where you replace both action name and controller name with the correct values according to your solution.
2- For the passed model, if this action is being rendered inside a view that has a Model property of Profiles
, then you don't have to specify the model to be passed to the action, as it will implicitly read it from the parent view.
if this is not the case, then you will need to store your Profiles values inside a medium variable (for example inside a ViewBag property) and then you will pass it when calling the action, so it should work on this passed model istead of working on the parent view one.
example: #Html.RenderAction("ACTION_NAME","CONTROLLER_NAME", YOUR_MODEL_VALUE_HERE)
Suggestion: if this parital view will just render the list passed, you can skip creating the mentioned action, and just make a call which can render the partial view, passing to it the correct list so it can work with.
To make it more clear, using your question I can see that the action named GetData is just constructing the list called Vertical from the Profiles model passed, so you can construct this list in your original action (Index, Details, WHAT_EVER_THE_NAME_IS) and store it in a ViewBag, then you can call RenderParial instead of RenderAction and this should result in the same output as your mentioned scenario.
example: #{ Html.Partial("ViewName", YOUR_MODEL_HERE);}
#{Html.RenderAction("actionName","controllerName");}
From your main view, you may simply render your Partial view as:
#Html.Partial("_PartialViewName", VerticalList);
VerticalList in this case will be the list of type VerticalContainer.Models.Vertical, that you populated in controller action.
In my _Layout.cshtml file, I'd like to invoke something like this:
<div id="content">
<div id="left-wrapper" class="box">
#Html.Action("FreeThisWeek", "Products")
#RenderBody()
</div>
</div>
And this is my ProductsController file:
[ChildActionOnly]
public ActionResult FreeThisWeek()
{
//Some code that fetches the data and builds the model.
var model = BuildFreeProducts();
return View(model);
}
If I try to run this code, I get a StackOverflowException because the Action returns the View() which asks for the Layout, which runs the Action which returns the View(), and so on.
Understandable, but how do I accomplish this which correct code?
Where do I write the View that compounds this data model with the HTML I write?
try returning PartialView("yourview",model) . Make sure the view you are returning does not use this page as a layout. you can specify that by using #{Layout=null} at the top of the view you are returning.
You are returning the View inside your FreeThisWeek Action and inside the View you are using the _Layout again. So it become recursive.
Go to your FreeThisWeek View and set Layout as null
#{
Layout=null;
}