Correct way to use _viewstart.cshtml and partial Razor views? - razor

I'm using _viewstart.cshtml to automagically assign the same Razor Layout to my views.
It's a dead simple file in the root of my Views folder that looks like this:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
This is more DRY than adding the #Layout directive to every single view.
However, this poses a problem for Razor partial views, because they run the contents of _viewstart.cshtml and therefore incorrectly assign themselves a layout, which makes them, um, no longer partial.
Here's a hypothetical project, showing the _viewstart.cshtml file, the shared _layout.shtml file, and a partial view ("AnonBar.cshtml").
Currently, the way that I'm getting around this is by adding the following line to every partial view:
#{
Layout = "";
}
This seems like the wrong way to denote a view as a partial in Razor. (Note that unlike the web forms view engine, the file extension is the same for partial views.)
Other options I considered but that are even worse:
Putting all partial views into a common folder, so they could share a common _viewstart.cshtml. This breaks the convention of views being in the same folder as their controller.
Not using partial views.
Is this something that is still being fleshed out by the Razor view engine team, or am I missing a fundamental concept?

If you return PartialView() from your controllers (instead of return View()), then _viewstart.cshtml will not be executed.

Related

ControllerActionInvoker & asp.net core Razor Pages

The ControllerActionInvoker work with MVC controller to select an action. Is there something equivalent to choose a Razor Page between two pages?
I have two Razor Pages RazorPage1.cshtml and RazorPage2.cshtml. I want to use a logic to load either RazorPage1 or RazorPage2.
You can render then as Partial view base on you conditional logic in parent view
Or
In controller you can write a conditional logic to render different view based on view name

Use of #{if-else} tags in PLAY templates

I am working since last few months with PLAY 1.2.5 using Java and HTML for views. I am aware of using JAVA code in PLAY templates using %{ if ------else}% (kind of as we use scriplets in J2EE. But now I came across use of tags like #{if}---{/if}. I searched around and found that this also is a way of using if-else. But my query is that in a similar piece of code I saw the following:
#{if some variable value in Controller == 'true'} ------- #{/if} #{else}------ #{/else} .
Now I don't understand how this Controller variable is accessed in controller within these tags. I have looked around and found that no such variable was rendered by render() or renderArgs() from the controller.
Is there any other way of using those variables/methods on templates which are declared in controllers or model for that matter?

.NET MVC 4.5 - Section not defined

I'm rendering a Razor template and would like to define sections, to which I'm able to add content throughout all included pages (namely, javascripts).
However, all sections so far have come up as empty. If I set them to required: true, I get the error that the section has not been defined. To test this, I added the following code to my main template file:
#section foo {
<p>Hello</p>
}
#RenderSection("foo", true)
These lines are right on top of each other. The rendering of the template fails with the message Section not defined: "foo".
Given that the section is obviously defined, did I maybe miss something in the Project configuration or Controller to enable support for sections? All other #commands (like #RenderBody())inside the template seem to work fine, so some support for the Razor commands is clearly present.
It looks like you're defining your section and trying to render it from your shared layout. As I understand it, you need to call RenderSection in your shared layout and then define the section it your views that use that shared layout.
This link from Scott Gu is a pretty good reference for sections:
MVC 3 Layouts & Sections

Passing Razor Markup to view and process it

I've searched the internet for days now with no luck finding this.
My model has a property which holds a chunk of html containing Razor markup.
exmaple:
public class ViewModel
{
public string Content = "<div>#Html.TextBox(\"UserName\")</div>";
}
In the view, I display that with
#Html.Raw(Server.HtmlDecode(Model.Content).toString())
I need to be able to convert the Razor markup into html, although because the Content is dropped in through the model, the view engine doesn't process it.
I have tried simply dropping in the Content, using just .Raw(Model.Content), .Encode(Model.Content), nothing works.
Any thoughts?
You could use the RazorEngine package which allows you to parse and execute Razor code. This being said I would not recommend you giving your users the power of editing directly Razor templates. You are opening a huge security hole in your website.
There are other templating engines such as DotLiquid for example which are better suited for scenarios where you don't trust user input.

Multiple views for 1 controller - Play Framework [duplicate]

If i want to have a common piece of UI across multiple pages, such as a menu, what is the recommended way to do this?
It would contain both template code and a back-end controller (similar to "snippets" in the LiftWeb framework).
I am aware that there is a menu module for Play, but I'm more interested in how this would be achieved in general.
There are two ways to include common view code into the Play Framework.
You can use the #{include} tag or the #{extends} tag.
The extends tag, as the name suggests, extends from a parent view. The extends tag is used by default in the skeleton code set up by Play when you create a new application. It extends the main.html. You add your code here.
The includes tag, allows you to inject a common piece of view code into your templates at a specified point. This works in much the same was a php include/require, or jsp includes work.
The problem will come when your template code also requires data or logic from the model (via the controller). If this is the case, then you will need to use the #Before or #With notation in your controller to ensure that the common piece of controller code is executed each time. You can add any data to the renderArgs list, so that it is available for use within the view.
A simple example of using renderArgs would be.
#Before
private static void commonData() {
// do your logic here
renderArgs.put("menu", menu);
renderArgs.put("selected", selectedMenuItem);
}
the values you have put into renderArgs (menu and selected in the example) will be available just in the same way as if you passed them into the render method.