How do I avoid calling the MVC _ViewStart for one page? - asp.net-mvc

I need to call the _ViewStart layout page for every page exept one.
How do I skip it for just one page (let's call it a.cshtml)?

You can just add this to the top of the page you don't want to use the layout for.
#{
Layout = "";
}

Source SO
As per this post by marcind
If you return PartialView() from your controllers (instead of return View()), then _viewstart.cshtml will not be executed.

Related

Does the layout or the view get loaded first in ASP.NET MVC?

I've read somewhere that in ASP.NET MVC, the view gets "loaded" before the layout (the view logic gets applied before the layout logic). So I was wondering what's the real answer here, and is there a way to check this?
If you mean what view get rendered in which order you can simply add debug statements to the views to find out. For example:
_Layout.cshtml
#{ System.Diagnostics.Debug.WriteLine("Pre-RenderBody()");}
#RenderBody()
#{ System.Diagnostics.Debug.WriteLine("Post-RenderBody()");}
index.cshtml
#{ System.Diagnostics.Debug.WriteLine("index.cshtml:start");}
<div>Home Page</div>
#{ System.Diagnostics.Debug.WriteLine("index.cshtml:end");}
Show ouput from: [Debug]:
index.cshtml:start
index.cshtml:end
Pre-RenderBody()
Post-RenderBody()
So the index.cshtml is executed first. Then the layout, and the content is inserted (not really the right term as it's actually appended to the stream/string/stringbuilder prior to everything after #RenderBody()).
The server returns whole HTML rendered from the view and layout.
I would say that the layout logic gets loaded "first." For example, I have logic in my _layout that states:
#if (User.isAdmin)
{
#Html.ActionLink("Settings", "Index","Admin")
}
Saying that if the users role is admin then allow them to view/click the settings button. So the layout logic would have to load "first."

Casual layout patern in mvc with razor

I can't find the reel intentions behind MVC-Razor layouts through internet.
In shared folder, there is :
_Layout.cshtml
_LoginPartial.cshtml
Should i use the _Layout for pages that dosen't require to be logged in, and use _LoginPartial for pages that require to be logged in ? Or am i completely lost ?
To make it simple :
If i create a new view that can only be reached when logged in, should it be beginning with
Layout = "~/Views/Shared/_Layout.cshtml";
or
Layout = "~/Views/Shared/_LoginPartial.cshtml";
?
Edit :
Checking tutorials and explanation from everyone (thanks all)
_Layout.cshtml is exactly like a master page in WEB FORM,
So i should always use :
Layout = "~/Views/Shared/_Layout.cshtml";
at the begining of a page i want to have formated like others.
The Login partial can be applied after authentification to alter the layout (disconnect button instead of connect, ect.)
The file _Layout.cshtml represent the layout of each page in the application. While partial view is a custom, reusable component that you can use in each page you need it. For example, we can create a partial view for customer and call it many time in page
<table class="table table-condensed">
#foreach (var student in Model.Students)
{
#Html.Partial("_StudentForm ", student)
}
</table>
So _Layout is meant to be used for all pages and _LoginPartial.cshtml can be used inside the page you need to have a login form in. Check this article about partial view
Tips and Tricks about Razor Partial Views
Layout = "~/Views/Shared/_Layout.cshtml";
in your view start file (_ViewStart.cshtml), may times its the ONLY thing in that file.
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
the _Layout.cshtml and _Viewstart.cshtml combo is similar to a master page in web applications but these will not have controller actions associated with them. if you set the layout setting in the _ViewStart file you don't need to set it in your actual views, they will inherit it from the viewstart file.
If you look inside the layout file you will see this line somewhere
#RenderBody()
That is where your individual views HTML will end up when your specific view is called.
The Login partial is just a quick start to demonstrate a view that can change display based on if the user is logged in or not.
You can use the same _Layout.cshtml but your controller ActionMethod should change to Authenticate. Use the below link for more info.
Authenticate User in MVC
Its more of a naming convention for layouts.
views will inherit it from the viewstart file. If you look inside the layout file you will see the renderbody method.
#RenderBody()
This is where the HTML code is read and shown in the browser.
The same goes for the _loginPartial.cshtml its just there for looks and to show you what Mvc is capable of.
Visual Studio creates the layout _Layout.cshtml when all but
the Empty project template is used. This layout is applied to all views by default through the /Views/_ViewStart.cshtml file.
If you do not want the default layout applied to views, you can change the settings in _ViewStart.cshtml (or delete the file entirely) to specify another layout in the view, like this:
#{
Layout = "~/Views/Shared/MyLayout.cshtml";
}
Or you can disable any layout for a given view, like this:
#{
Layout = null;
}
Hope this helps.

ASP.NET MVC : does a partial know if it is bring requested from another page?

I have a partial view which can either be requested via an Action (Action2 in the image below), or rendered inside another page with "Html.Action()" (Action1 in the image below). From within the partial (or the partials controller) is there a way to determine which of these two methods were used to render the page?
You can use ControllerContext.IsChildAction or check DataTokens whether there is something with key "ParentActionViewContext" if you don't have access to ControllerContext.
You should be able to get it from
HttpContext.Current.Request.RawUrl
It should be noted that it is not particularly good practise to do this sort of thing in MVC. The partial should not be concerned about its "parent" ... but if you do need to do this, for whatever reason ...
You can use this code in the partial view's controller to determine if it was loaded directly or included in another page.
// this is the route which was originally used to route the request
string req_controller = Request.RequestContext.RouteData.Values["controller"].ToString();
string req_action = Request.RequestContext.RouteData.Values["action"].ToString();
// this is the route which was used to route to this action/view
string this_controller = RouteData.Values["controller"].ToString();
string this_action = RouteData.Values["action"].ToString();
if (req_controller == this_controller && req_action == this_action)
{
// this partial was loaded directly
}
else
{
// this partial was loaded indirectly
}
my reason for wanting to know this is that I wanted to be able to switch the Layout of a partial view based on whether or not it was rendered from a controller action or from within another page.
ie.
return PartialView("MyView.cshtml");
would result in a layout with the requisite menu bars and other site trimmings.
and
#Html.Partial("MyView")
would just embed the content without adding the rest of the page.
so, in my page's default Layout I have:
#if (this.IsPartial()) {
Layout = null;
} else {
Layout = "_SiteLayout";
}
#RenderBody()
here's what I found:
public static bool IsPartialResult(this WebPageBase #this)
{
return !#this.OutputStack.Any(writer => writer is HttpWriter);
}
it probably won't work in all situations. but it works for me. YMMV/HTH
No, there is no way and a partial shouldn't need to know it.

ASP MVC 3 use different Layouts in different views

I have an ASP MVC application which needs multiple different layouts. In ASP.NET Web Apps I would have just made separate master pages. How do I do this in ASP MVC 3?
So far I have made a separate Layout.cshtml file for each layout I need.
I tried setting the layout in the view but it is getting blown away from the ViewStart.cshtml which is setting it back to the default layout for the site.
Also, I can't seem to get intellisense working with Razor so I haven't been able to explore much of what I can do in the ViewStart, if I can conditionally set the Layout, or what.
Thoughts?
You could set the layout dynamically in your controller action:
public ActionResult Index()
{
var viewModel = ...
return View("Index", "_SomeSpecialLayout", viewModel);
}
You can manually set the layout for a view by writing #{ Layout = "~/.../Something.cshtml"; } on top.
EDIT: You can pass the layout name as a parameter to the View() method in the controller.
This method is the simplest way for beginners to control layout rendering in your ASP.NET MVC application. We can identify the controller and render the layouts as per controller. To do this we write our code in the _ViewStart file in the root directory of the Views folder. The following is an example of how it can be done.
#{
var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
string cLayout = "~/Views/Shared/_Layout.cshtml";
if (controller == "Webmaster") {
cLayout = "~/Views/Shared/_WebmasterLayout.cshtml";
}
Layout = cLayout;
}

Disable layout in ASP.NET MVC?

In MonoRail you can just CancelLayout() to not render the layout. In ASP.NET MVC, the only way to affect the layout seems to be to pass the layout name into the View() method like View("myview", "mylayout"); only it seems that passing null or an empty string doesn't do what I'd want.
I ended up creating an empty layout that just rendered the content, but that seems silly.
"Not Render the layout" means exactly that. In the web forms view engine they call layouts "master pages". I want to render just my action's view and not surround it with the master page.
In MVC 3, you can remove the master layout code with:
#{
Layout = "";
}
At the beginning of view add this:
#{
Layout = null;
}
If you want style sheet to remain, you'll need to add reference to it in that view.
To disable this for all pages, edit the _ViewStart.cshtml (in the root, under the 'Views' folder), and ensure that it contains the following:
#{
Layout = null;
}
And to enable the template for any specific view, the following can be added to the .cshtml file for that view, to enable the template:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
In the Controller action we can set the required layout.
return View("Index", "_LAYOUT_NAME", model);
https://stackoverflow.com/a/5161384/2039603
I see in the right answer it says that "It seems this was impossible in the version of ASP.NET MVC"
Which version are you using? Because I found the solution (I had the same issue) to your problem
So, to Disable Layout in the page, you should use:
#{
Layout = null;
}
And, as suggested here, this could solve your problem:
public ActionResult Index()
{
SampleModel model = new SampleModel();
//Any Logic
return View("Index", "_WebmasterLayout", model);
}
Instead of using a normal view, create a partial view. These can then be used on their own, which acts very much like CancelLayout() - or you can incorporate them into a view that references the Master Page, in which case it will be the full layout. They are also useful if you want to send back a partial HTML chunk in response to an AJAX request.
Not having any luck trying to set the masterPage parameter to "" or null and returning a View (like I didn't)?
Then try this and use PartialView instead:
public ActionResult Article(string id)
{
return PartialView("~/Areas/Store/Views/CustomerService/" + id);
}
I needed to do this to load the contents of a view asynchronously from JS.
It seems this was impossible in the version of ASP.NET MVC I was asking about.
You can create a custom ActionResult that does pretty much anything. The ActionResult controls what is sent back to the client as the response. It would be trivial to create a class that extends ActionResult that does nothing.
One alternative is to actually specify a layout but make that layout empty
"_EmptyLayout.cshtml" that contains nothing or just a comment that says it contains nothing so later someone sees it as intended.

Resources