.net - How to use "RenderBody()" in partial view when the partial view is shared across layout pages? -
following exact scenario in asp.net mvc application:
there 2 layout pages quite identical each other. 1 having angular related attributes in "" tag, whereas other non-angular layout. in order avoid duplicate markup in both razor layout files, thought create partial view , share across layout pages.
following partial view (razor), have named "_layoutpartial":
_layoutpartial.cshtml
<div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @html.actionlink("application name", "index", "home", new { area = "" }, new { @class = "navbar-brand" }) </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@html.actionlink("home", "index", "home")</li> <li>@html.actionlink("about", "about", "home")</li> <li>@html.actionlink("contact", "contact", "home")</li> </ul> @html.partial("_loginpartial") </div> </div> </div> <div class="container body-content"> @renderbody() <hr /> <footer> <p>© @datetime.now.year - asp.net application</p> </footer> </div>
the above partial view shared in "_layout.cshtml", , "_angularlayout.cshtml" per below:
_layout.cshtml
<body> @html.partial("_layoutpartial") @scripts.render("~/bundles/jquery") @scripts.render("~/bundles/bootstrap") @rendersection("scripts", required: false) </body>
_angularlayout.cshtml
<body ng-app="myangularlab"> @html.partial("_layoutpartial") @scripts.render("~/bundles/jquery") @scripts.render("~/bundles/bootstrap") @rendersection("scripts", required: false) </body>
when try run mvc application, following error:
the file "~/views/shared/_layoutpartial.cshtml" cannot requested directly because calls "renderbody" method.
the error message obvious, , seems can use renderbody method in master page, , not anywhere else. keen know how can have 2 identical layout pages (with little differences shown in example) writing common code instead of keeping duplicate code in both layout pages?
i think need use "nested layout" putting 1 layout page "master page" other layouts, similar webforms counterpart:
_baselayout.cshtml
<html> <head> <!-- other header tags (link, meta, title etc.) --> @scripts.render("~/bundles/jquery") @scripts.render("~/bundles/bootstrap") <!-- js & css includes if available --> </head> <body> <div class="navbar navbar-inverse navbar-fixed-top"> <!-- other elements --> </div> <div class="container body-content"> @renderbody() <!-- other elements --> </div> @rendersection("scripts", required: false) </body> </html>
_layout.cshtml
@{ layout = "~/views/shared/_baselayout.cshtml"; } // put reference base layout here <div> <!-- non-angular layout --> @renderbody() </div>
_angularlayout.cshtml
@{ layout = "~/views/shared/_baselayout.cshtml"; } // put reference base layout here <div ng-app="myangularlab"> <!-- angular layout --> @renderbody() </div>
advantages using "nested layout":
eliminates need repeat
@styles.render
&@scripts.render
,@rendersection
(they're inserted automatically every pages referencing base layout).eliminates need use more 1
body
tag, replacediv
tag hold view page contents.
the file "x" cannot requested directly because calls "renderbody" method originated html.partial
called directly child layouts, a layout page renderbody
method can't requested directly template.
if want set default layout nested layout, put 1 of child layout reference in _viewstart.cshtml
:
@{ layout = "~/views/shared/_layout.cshtml"; }
another note: partial views intended use in view pages, not in layout pages. layout pages used placeholder view pages - not directly accessed action methods.
Comments
Post a Comment