Static HTML page in ASP.NET MVC that does not use Layout - c#

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;}

Related

How to go to a View in Shared folder from a View in Home folder in MVC using C#

I am trying to access a PartialView in Shared folder by clicking an Html.ActionLink HelperMethod present on a view in Home Folder as:
#Html.ActionLink("Create New", "~/Views/Shared/_AddBranch.cshtml");
with fail. I dont want to add a new controller to achieve this but I don't mind replacing Html.ActionLink with another tool if I need to. Anyone knows how to do it?
You should not be generating an anchor tag which points to the view file directly without an action method. Ideally you should create an action method throuh which you will render the view.
If you are trying to render some re-usable view. You should use Html.Partial method in your main page
#Html.Partial("~/Views/Shared/_AddBranch.cshtml")
Razor will include the HTML markup for the _AddBranch.cshtml when it renders your main page
If you want to pass a model/viewmodel to the partial, you can use this overload
#Html.Partial("~/Views/Shared/_AddBranch.cshtml",Model.YourModelYouWantToPass)
Assuming YourModelYouWantToPass is a property of the model of your main page and your partial view is strongly typed to the type of YourModelYouWantToPass property.

Cant i ADD another Layout which is other than default Layout in MVC4

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");
}

Avoiding .NET MVC controller calls with angular-ui-router

I am building a .NET MVC 5 application on back-end and Angularjs on front-end.
I am loading .cshtml views in a div containerOne on a parent .cshtml page with ui.router and everything is working fine. An issue I would like to solve is when I enter manually a page URL that is C# controller's action path(in the example I provided below it is /Proposal/Customers) - my view is loaded on a whole page. What I want to be called is a .state named 'customers' in my example, or something like that. My example code is(part of my proposalConfig.js):
.state('customers', {   
url: 'AllCustomers',
views: {
containerOne": {
templateUrl: '/Proposal/Customers'
}
}
});
On my back-end I have a ProposalController.cs and an action method Customers that calls a Customers.cshtml view.
Anyone has an idea how to solve this?
EDIT
The same thing happens if, instead of 'AllCustomers' I put '/Proposal/Customers', and then after the first load of a .state I refresh a page.
I forgot to mention that I have $locationProvider.hashPrefix('!').html5Mode(true); in a proposalConfig.js file.
If you mean that the entire page html markup (html tag, body tag and such)is being returned when you only want the specific content of the Customer.cshtml, which I also assume only has what you want in it, its probably because your view has a shared view start layout. Put this in Customer.cshtml
#{
Layout = null ;
}

What is the execution order of an MVC Razor view/layout

I have a razor layout like:
#using (var context = SetUpSomeContext()) {
<div>
Some content here
#RenderBody();
</div>
}
And a view like:
#{
Layout = "MyLayout.cshtml";
}
<div>#SomethingThatDependsOnContextBeingSetUp()</div>
When the view renders, SomethingThatDependsOnContextBeingSetUp executes before SetUpSomeContext and fails. This seems weird, because I would expect that not to execute until RenderBody is called in the layout. When I switch this to use a "PageContent" section instead of RenderBody, everything works as expected. Can anyone explain this behavior?
The Razor pipeline is:
First, Razor evaluates, if present, _ViewStart.cshtml that contains only Razor statements (C# or VB) for assign Layout or other initialization, it should never have html tags inside.
Then, it parse and evaluates the "View" cshtml file.
Then, it parse and evaluates, if present, the Layout, and when evaluates the #RenderBody method of the cshtml layout file, replaces it with the html script resulting from evaluation of "View" cshtml file.
Finally, it builds the html control graph objects of layout and view html files.
So, you cannot do depend any "Razor" objects of a view from layout operations, but rather you may put in _ViewStart.cshtml your initialization of objects visible to your view.
You may imagine cs(vb)html views as a static content loaded when Controller.View method is called.
At that point, the cshtml loaded content is parsed by Razor that evaluates the expressions (assign properties(as Layout), branchs, loops) and build a sort of binary tree or graph of "HtmlControls" objects into the ActionResult object returned by View method.
Next, ActionResult is rendered as html from Asp.Net and returned to the client as http response.
To do that, Razor parses cshtml files and carries out their code inside parts starting first from the "_ViewStart.cshtml" (also more of one if present in the sub folders chain related to the origin controller), then follows cshtml file loaded by conventions (name of view equals to the name of action in the path Views/[ControllerName]/), or by expressed view's name as parameter when calling View method, and finally, the eventual layout file linked to the view by Layout property.
Let me clarify this by investigating a situation,Assume that you have view like;
#renderSection("Header")
#using (var context = SetUpSomeContext()) {
<div>
Some content here
#RenderBody();
</div>
}
#renderSection("Footer")
And we are assuming that razor executes the page in the order you expect, what would happen if we declared our view like?
#{
Layout = null;
}
<div>#SomethingThatDependsOnContextBeingSetUp()</div>
Razor would not have any idea whether that view needs a layout page until executing #RenderBody().Also it would deduce that it rendered layout page for nothing and this would not be reasonable.So this is not what actually happens.
When request made it is so natural that Razor first executes body of your view.
If your view not specified layout like in my demo Razor only renders output of that page and stops there.If view has a layout specified like in your code
after executing the view , it passes control to layout page.(Layout page starts to render from top to bottom)So what is remaining for Layout page is only content placement.When it sees #RenderBody() it only places output of your already executed view.
For sections; they are not executed when your view body executed, after your view passes control to layout page,layout page explicitly invokes the execution of your sections in the order they are declared.
Also notice that you are specifying your page title in your view body and it is rendered in your layout title tag (ViewBag.Title).After executing view body all the variables which is declared in view body are available in layout page.
Sum:Rendering order is from top to bottom but execution order is different.
For your situation: "SomethingThatDependsOnContextBeingSetUp executes before SetUpSomeContext and fails". Like i said it is natural behaviour of Razor execution cycle, view body executed before layout page executed.When you make it section ; view body executed first but sections are not executed before layout page.View body passes control to layout page and Layout page starts to render from top to bottom and if it sees #RenderSection then invokes the execution of section.So in this case SetUpSomeContext is executed before SomethingThatDependsOnContextBeingSetUp executed.
The execution order is from innermost to outermost.
I would argue that using a 'context' the way you use it is not the best design - you should consider moving the setup to the controller / action filter and pass the data to the views in model.
If you require some logic on all your views, create a ViewModelBase that all your ViewModels inherit from.
Then in your Controller(Base) you can initialize the ViewModel.SharedContext and other properties.

Trying to use two layout pages on MVC4 and Razor

When I use #RenderBody on a view (not principal), I receive this message Error: The file "~/Views/Shared/_Sistema.cshtml" cannot be requested directly because it calls the "RenderBody" method.
I do not understand it as I am a novice in MVC.
What do I can do?
Thanks!
If you are using the Renderbody in _Sistema.cshtml file, then make it as a Layout page.
And add another partial page named like MyPartial.cshtml with Layout name as _Sistema.cshtml.
Renderbody is supposed to be in the master page only. i.e., Layout page.
So your _Sistema.cshtml page should only contains the following:
#RenderBody()
#RenderSection("scripts", required: false) #*----Optional---*#
Then your your new partial page MyPartial.cshtml should contain the following:
#{
Layout = "~/_Sistema.cshtml";
}
Then use your partial page in your view as follows:
#Html.Partial("MyPartial")
Hope it helps.
RenderBody is for masters only. This method renders markup of content pages that does not belong to any particular section. If your view calls RenderBody, two cases are possible:
Either this is a mistake and this view should not call it.
Or this view is a master, and you should instead use some other views inheriting layout from this master.
you just need to interact with _ViewStart.cshtml
and use if condition to specify the share mater page for each group of users.
for example user is admin then user _Layout.cshtm other wise use _Layout2.cshtml
use following code :
#{
if(User.Identity.Name.ToLower()=="admin") {
Layout = "~/Views/Shared/_Layout2.cshtml";
}
else {
Layout = "~/Views/Shared/_Layout.cshtml";
}
}
In my experience, I was struggling with this same issue for days. After further investigation, I found that when starting a new Umbraco site, I had the option to select templates. That resolved the RenderBody issue. When creating the layout page without the templates it doesn't see the Master page as the layout, hence not being able to call the RenderBody method. Using the templates automatically sets the Master page as the Layout allowing you to call the RenderBody. I hope this helps.

Categories

Resources