I am trying to render something like razor's render partial in dotvvm master page. but found nothing from the documentation but the following:
Master Page Nesting
You can also nest a master page in another master page and so on. Just use the #masterPage directive in the master page to specify parent master page.
Basically I want to render navigation menu which will be defined in another master page in my parent master page.
I think that you are looking for a Markup Control, see the docs for more details: https://www.dotvvm.com/docs/tutorials/control-development-markup-only-controls/2.0
In short, markup control allows you to declare custom control in a dothtml file. You can use all DotVVM features in the markup control, you'll just have to explicitly declare how data from the view model should be passed if you want to use data bindings.
A minimalist markup control may look like this:
<!-- The control must be used when data context is this view model: -->
#viewModel Full.Name.Of.MyViewModelBase
<ul class=menu>
<li>{{value: NameOfSomething}}</li>
<li>...</li>
</ul>
Then, the control must be registered, so DotVVM can find it:
// in DotvvmStartup
config.Markup.AddMarkupControl(tagPrefix: "cc", tagName: "MyMenu", "Views/MyMenu.dotcontrol");
After that, you can use the control anywhere you want (well, recursion works only sometimes 😃):
<cc:MyMenu />
You can also declare properties and then use it inside the control. It may help with reusability of the control since the view model does not have to fit. I'll leave it to the docs
Related
Ive noticed that there seems to be no real difference between a view and a partial view.
For instance, one can create a view but can render it as a partial view by using
#Html.Partial("ViewName")
or by specifying that its action return it as
return PartialView();
Ive noticed that the opposite is also the case - ie, one can create a partial view but if it is returned as a full view, it will be displayed with the default layout for the views.
My question is this -
When adding a new view in Visual Studio, one is given the option of creating a view that is partial or not. Isn't this redundant, since a view can be rendered as both a partial and a full view anyway?
There is difference between views and partial views, and the difference is more about their usage, rather than technical.
View is meant to be used as full page of your application, it needs layout, <html> and <title>. Partial views are more like reusable parts of other views. Partials do not represent full pages, they are inserted into other views.
From technical point of view, return View("SameView"); renders view including layout page, and returning that same view by return PartialView("SameView"); renders contents, but omits contents of layout page.
No difference - it's true. But when you say "Partial View" all your teammates understand that you mean reusable views that will be used in many places across the website.
Think of partial views as user controls in ASP.NET WebForms. Partial views are used if you want to have a functionality centralized, so it can be used in many parts of your website. This is the purpose of partial views.
Hope I have answered your question.
Two things. First, to an extent you are right. But it's more of a semantic thing to seperate reusable code. It also comes in handy when for e.g. say you need to display a dialog but only when the user has some sort of an interaction with the page, like the click of a button. With partial views you don't have to have the markup for this on the page when it loads thereby reducing the file size. When you write markup/code in the partial view, you don't have to do the whole <html></html> code block. Instead you just create a <div></div> or whatever you need.
The bit about creating a view in Visual Studio. No, it's not redundant because when you create a partial view, it does not use your master layout file.
Practically , there is no difference among them. But when you acknowledge an html object as Partial View then, it is considered as a self-contained object which may get serve at different places just like a web-part/User-Controls and also its lightweight.
Partial view kept to use as partial page of the main page(parent page).
What does mean of partial view? Actually in the main page we will have all the HTML page attributes as below:
html lang="en"
head
title
meta
body
But in partial view we will not have all above attributes.
Find the features of partial page:
1. Partial page will be light wait and get fitted into the any view.
2. This will use as the reusable component.
3. Partial view will be render inside of a View(parent view or page).
For all who coming from ASP.Net background they can understand partial view as user control.
Thanks
Afazal
mdafazal#gmail.com
To answer your question specifically, when adding a new view in Visual Studio, you will get some very basic markup generated for you as a starting point, based off of your selections in the dialog.
Here is the generated markup in Visual Studio 2010 (VB.NET) for the different combinations of the "Partial" checkbox and the "Layout" checkbox:
# "Create as a partial view" unchecked
# "Use a layout or master page:" unchecked
#Code
Layout = Nothing
End Code
<!DOCTYPE html>
<html>
<head runat="server">
<meta name="viewport" content="width=device-width" />
<title>MyView</title>
</head>
<body>
<div>
</div>
</body>
</html>
# "Create as a partial view" unchecked
# "Use a layout or master page:" checked
#Code
ViewData("Title") = "MyView"
Layout = "~/ThePath/ToThe/Layout.vbhtml"
End Code
<h2>MyView</h2>
# "Create as a partial view" checked
# "Use a layout or master page:" greyed out
# returns an empty file
As you can see there is nothing fancy going on in the background or special properties being set in a secret file somewhere. The options are simply used to get some default markup on the page. Whether or not this is practical is purely subjective!
Quite late but might be useful for someone with the same question. Partial views are helpful in a scenario where you want to load a view based on some user selection.
For instance, let's assume there is a dropdown in parent view displaying three operations that the user can perform. Based on the user selection, a partial view can be loaded into the parent view instead of keeping hidden DIVs in the parent view itself, thus making the parent view light. This will be very useful when we have multiple such user selections based DIVs
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.
I'm using the typical built in view engine in mvc3 (is there a proper name for it?) for views and master pages and it's including a Razor partial view on the .aspx page. In the masterpage, there is a ContentPlaceHolder with an ID of "ScriptContent".
I want to be able to fill that ContentPlaceHolder from within the Razor partial view but I don't think this is possible. Does anyone know if it is possible and how I would go about doing that?
I already tried rendering it in the partial like so, but that didn't work.
#section ScriptContent {
... content ...
}
It would be very difficult, so much so that I'd recommend finding another way :(. I wish it was easier, but these are the complexities of integrating a new view engine into an existing legacy system.
To give you a head start if you really want to try it: You'd probably need to create a custom base class inheriting from WebViewPage for your Razor content pages, override some of the methods (honestly I'm not too familiar with that aspect so you'd need to debug to follow the pipeline) so that instead of treating the Layout property as the path to a Layout page, you treat it as a Master page. Then you'd need to instantiate the master page and somehow convert the Sections (which were transformed into calls to DefineSection by the Razor parser, and should be stored in a Dictionary somewhere on the base class) in to Content controls and stuff them in the Master Page.
If I haven't boggled your mind by this point, you may just be able to pull this off, but to be honest, I'd avoid it.
P.S. We refer to the older view engine as "ASPX", based on its file extension ;).
I have a ASP.Net MVC view which contains other partial views derived of ViewUserControl. The view itself is contained in a master page, so the control hierarchy can be summarized as follows:
Master page - basic settings
ViewPage - "the" page
ViewUserControl - content component 1
ViewUserControl - content component 2
...
ViewUserControl - content component n
Additionally, we have a custom control for the declaration of CSS and Javascript files. This custom control ensures that, no matter how deep into the hierarchy, whenever there is a CSS or JS dependency it will be rendered inside the Page.Header, thus avoiding scattered and duplicated references. Let's call this custom control <my:dependency>.
All is well when <my:dependency> is hosted in the master or ViewPage. But if I use it deeper inside the content components, Page.Header is null. Debugging revealed that, for controls hosted in a ViewUserControl, their Page is the very ViewUserControl in which they're in, and so the Header is indeed missing.
How can I make <my:dependency> "see" the topmost ViewPage and get access to the Header? Thanks.
Now I could be wrong, but you appear to be trying to get a web forms control to work in MVC, something that is not recommended for reasons you've discovered.
You might want to look at something involving the ViewData collection.
Simon
I'm looking for a way to (preferably) strongly type a master page from a user control which is found in a content page that uses the master page.
Sadly, you can't use this in a user control:
<%# MasterType VirtualPath="~/Masters/Whatever.master" %>
I'm trying to access a property of the master page from the user control and would rather not have to pass the property from the master page to the content page to the user control because multiple content pages use the same user control. One change, one place whatnot.
Try Page.Master.
Whatever whatev = (Whatever)Page.Master;
You'll have to make sure you add the proper using statements to the top of your file, or qualify the Master page type inline.
One potential gotcha is if this control is used by a different page whose master page is NOT the same type. This would only get caught at runtime.
Have you tryed Page.FindControl("name") on the usercontrol?
The best way to do it that I've found is actually to build a custom class that is based off of UserControl, give it a Master property with a get accessor that fishes through the this.Page.Parent until it stops encountering master pages (If you are nesting, this step is unnecessary otherwise) and then return that web control as the type of the master page you want to use. Then, when you add a new user control, change it's base class to the name of your custom class. The .Master property will be accessible and cast properly as the master page you want it to use.
In VB all I needed to do was change this:
Dim lAuthLevel As Integer = Master.MasterContact.AuthenticationLevel
to this:
Dim lAuthLevel As Integer = CType(Me.Page.Master, main).MasterContact.AuthenticationLevel
So all references of Master become Ctype(Me.Page.Master, typeofMaster)
Where is in this case the word "main" - get that from the declaration at the top of the master page. e.g.
So "main" in this case :)