MVC3 Razor layout base class from View - layout

In MVC with web forms you can set a MasterType like so:
<%# MasterType TypeName="FooMasterPage" %>
Which gives you a reference to the base class of the master page, which you can then use in the View like this:
<% Master.title = "foo" %>
With Razor we can specify base classes for our Layouts but it seems we cannot access them from our View. Is this really not possible? The only work around I see is using ViewBag/ViewData, which works but adds an extra layer of effort and overhead.
Is there any way to reference the instance of a Layout page's base class from the View?

I cannot think of any scenario why someone developing an ASP.NET MVC application would ever need to provide a common base type for the master page. This would mean that you are writing something like a codebehind and that kinda sticks in MVC. The fact that you could do this in the WebForms view engine is because this is an heritage from classic WebForms but that doesn't mean that it is something that should be done. There are so many ways to include common functionality in ASP.NET MVC varying from ViewModels, usage of custom HTML helpers, usage of partials, usage of Html.Action, usage of razor sections, etc...

Regardless of whether or not you should do something like this in MVC (and I agree with Darin's points) it is simply impossible in Razor, and that is because Razor views get rendered in a single pass starting with the view first. Which layout page will be used is not even known until after the view is done executing.
In contrast, the aspx view engine performs multiple passes where the page/master control tree is first instantiated, then hooked up, then some events occur (which are useful in WebForms but not in MVC) and then rendering happens. It's this concept of the control tree that lets you refer to the Master page from a view page. Razor doesn't have that.
ViewBag/ViewData are the recommended mechanisms for passing data from views to layouts in Razor.

Related

Blazor .NET Core 3.0 - Can cshtml pages use MainLayout.razor

With previous versions of Blazor all files were cshtml pages and were able to use _layout similar to MVC projects - all was well.
But now in the new .NET Core 3.0 release Blazor template switched to *.razor files which are razor components (not razor pages). And the layout is now Shared/MainLayout.razor and is applied via routing in App.razor file:
<RouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)" />
So this creates confusion. We're still able to add razor pages (.cshtml files) to the project but they do not get the layout applied. It would be a pain to create and maintain 2 separate identical layouts, 1 for razor pages and 1 for razor components. I was unable to find any guidance for this.
Is there any way to apply razor component layout (Shared/MainLayout.razor) to razor pages (.cshtml files) inside the same project? Of if not, what is the recommended approach?
The quick answer is no. Currently you can load Razor Components into a Razor Page but can’t load a Razor Page in a Razor Component. This is stated in the official docs.
I’m not sure there is a recommended approach as such - Except to try and refactor to Razor Components as much as possible, if using components everywhere is your goal.
If you want to keep a mix then I would suggest sticking with Razor Pages as pages (hope that makes sense) and only use components within those pages. That way you would only need the one Layout type.
in the head of your _Layout page add
<base href="~/" />
in the bottom of body add
<script src="_framework/blazor.server.js"></script>
then in your
_Host.cshtml
file add
#{
Layout = "_Layout"; //your Layout name
}
for more information follow this link
I currently have the same problem and it's really annoying. Would also be interested in a solution for this. I can't even load the layout with
#{
Layout = "shared/MainLayout.razor";
}
because it expects a file with the name MainLayout.razor.cshtml then.

When to go for getViewForPage in Hybris

I have seen methods in Hybris returning a JSP or dynamically doing getViewForPage.What is the difference between the two approaches.Is it the static or dynamic difference?What should be used when?Can I add new components with just returning a JSP using return statement?
I would strongly recommend to use the getViewForPage method every time. There are a lot of reasons why. Here are just the 2 most important from my point of view:
For every CMS Page Template you can define the "frontendTemplateName", which is the reference to the JSP view. The advantage here is that it can be maintained in the database. So if you decide to use a different JSP to display a CMS Page Template, all you need is to change the frontend template name and hybris uses a different JSP to render this template. This advantage is gone if you return just the JSP file. It also helps to avoid repetition of the JSP name in your code.
Additionally consider restrictions to pages. hybris is able to display different pages depending on maintained restrictions. It is not possible to use restrictions on CMS Pages when using the JSP name in your code.
As long as you use the "storeCmsPageInModel" method, you can use CMS Components in your template. No matter if you use JSP or getViewForPage. However with the getViewForPage method you make sure, that the right JSP is used and that the configured frontend template name has the right content slots to display your components.
Maybe this question is not intended, but I would strongly recommend to use CMS Pages for every possible purpose. We developers have seen requirements change over time and CMS Pages offer all the flexibility you need to respond to this change.

Liferay: How can I get the pages of the site in a web content?

I have a portal in Liferay 6.2, and need to design the velocity template of a web content that must have a menu listing the pages (linked names) of the site where is present.
My questions are:
Is this possible?
What would be the correct way to do this?
Would it be better to make a portlet instead of a web content for this purpose?
Thanks for the help.
It feels a bit like you are trying to solve many problems in a single template - consider to compose the UI from many different elements (e.g. custom portlets) rather than building the one structure/template that fits all requirements.
That being said, as there's also the chance that your template doesn't do more than just displaying the current navigation: You have two options: The out-of-the-box Navigation portlet is quite configurable, you might be able to utilize that one instead of implementing anything yourself (check the configuration options).
And lastly, if you want to implement for yourself: Get hold of the themeDisplay object. With getLayout() you'll get the current page, while getLayouts() you'll get all pages of the current site and can enumerate them. However, there's one problem: You typically don't have access to the themeDisplay object from a CMS template. But there are several ways to still get to the data (search the Liferay forums for cms template themedisplay). Also, an Application Display Template will be a lot more powerful - and you can also check how the layouts collection is built - just search for usage of ThemeDisplay.setLayouts in Liferay's source code. But with ADT we're diverting from your original question.
Liferay offers a sitemap portlet out-of-the-box which lists pages of a site. You can configure it and define your own application display template (ADT).

For Silverlight web resources should we place xap or HTML on entity form

Normally we get two choices in case of Silverlight solutions. We can place either xap or html web resource on the entity form. I am not sure which approach is better. I found in many cases both work. MSDN example suggests to use html but I also found examples on various websites using directly xap.
Recently I found a particular case that Xrm.Page.Data works in case of xap but not in case of html. So I am again wondering which approach is better. What are the advantages of using one over the other.
TIA
The main distinct difference I've found is that by embedding a Xap file straight into the form it has direct access to the Xrm property and can access form fields much easier.
If this was in a web resource, you either need to have javascript in the web resource such as
var Xrm = window.parent.Xrm
Which will set an Xrm variable in your Html resource to the Xrm property on the form and you can then pull it into your silverlight application to get at fields and properties.
The main difference is to do with where you want to embed your silverlight web resource. I wanted to put mine that i'm currently working on in the left hand nav on the form as its own individual page. This required editing the form adding a new Nav item but this only allows adding of a HTML web resource, so I had to embed my Silverlight App in this to get it to display.
So in summary, the advantage of direct embedding is for access form properties. But in terms of usage it depends on what it is your trying to achieve.

MVC3 structure in IIS

I am making several web applications. What I want to do here is:
Applications should stand alone in IIS using differnt application pool.
There is one main application used solo as front page, allowing log in/out and navigate users to other applications.
I want other applications to use the layout of the main application.
The structure I was thinking was to deploy the main application under root folder of the website and host other applications under it in seperate folder (seperate application and pool). Something like:
IIS
|
|__Main app (web site)
|
|__App1
|
|__App2
However, I just got confused here:
How can I reuse the layout/dll acorss apps/pools without copying them into each application (Maybe it's a silly question)
How can I use MVC3 controller/action feature instead of directly using hard coded <a/> to navigate users to each application. I actually tried it. Looks like the Main app (MVC3) can only recognize controller and view in it's own project.
In summary, what I try to do is: Deploying my applications in the tree sturcture above and let the main app bring views from sub apps and display in main app's frame.
Maybe it's not a good practise, but any suggetion is welcomed!!!
Thanks a lot
It really sounds like you would want to make use of Areas in MVC. This wouldn't allow you to run the nested "applications" in their own App Pool, but it would accomplish everything else you are looking to do (shared layouts, dlls, Html.ActionLink, roles based access to each Area, etc). You can easily share top level navigation across all Areas and have different sub navigation for each. I have a 2 part blog post about using a single layout that is shared across Areas that might give you some help (or ideas).
Single Layout for Areas with ASPX and Razor views (Part 1) - Using the ASPX View Engine
Single Layout for Areas with ASPX and Razor views (Part 2) - Using the Razor View Engine
If you felt that having sub apps in Areas in a single project was too rigid you could also look into using MvcContrib to make your sub apps in Portable Areas and then consume them in your top level app.

Resources