How to replace current layout at runtime? - asp.net-mvc

I have a little app (asp.net mvc).
I have a question: in my project i have a layout - _layout.chtml,
It's possible to replace the content with different content that i inject from a file?
For example:
Current _layout.chtml:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
#RenderBody()
</body>
</html>
Now, i want to load new content from a file and replace the current _layout with new content as follows:
<!DOCTYPE html>
<html>
<head>
<title>My Title</title>
<link href="~/css/mycss.css" rel="stylesheet" />
</head>
<body>
#RenderPage("../Shared/_Header2.cshtml")
#RenderBody()
#RenderPage("../Shared/_Footer2.cshtml")
<script src="~/scripts/jquery.js"></script>
<script src="~/scripts/angular.js"></script>
#RenderSection("scripts", required: false)
</body>
</html>
How do i can to do that?
Thanks!

If you don't want overwrite your _ViewStart.cshtml you some other ways
return View ("NameOfView",masterName:"viewName");
Or
store your layout in viewData like
//in controller
ViewData["Layout"]="your layout path";
//in _ViewStart.cshtml
Layout = ViewData["Layout"];
Or you can create a custom attribiute and set your layout name in it like
[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
return View();
}
for more information check this answer specify different Layouts

I'll assume you're calling a new controller action at the time where you want to replace your layout. If so, then one of the following would do the trick;
First off you can put a _ViewStart.cshtml file in your \Views\ folder to override the default layout as seen below.
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
From here you can add another _ViewStart.cshtml file in \Views\User to override the default layout for all your \User\ views.
#{
Layout = "~/Views/Shared/_UserLayout.cshtml";
}
You can also specify the above in a view, e.g. for \Views\User\Index.cshtml.
#{
Layout = "~/Views/Shared/_UserIndexLayout.cshtml";
}
Or you can specify the layout when returning the view in the controller;
return View("Index", "~/Views/Shared/_UserLayout.cshtml", someViewModel);

Related

Where are fonts specified in MVC?

I'm teaching myself MVC and am having trouble with the fonts in the output web pages.
I have a View object that starts thus:-
#model IEnumerable<Beer.Models.Brewery>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/Index.cshtml";
}
<h2>Index</h2>
... etc etc
The file Beer\Views\Shared\Index.cshtml is:-
#{
ViewBag.Title = "Index";
}
<body>
#RenderBody()
</body>
When I run this the page is rendered in Times New Roman. I then change the Layout to:-
Layout = "~/Views/Shared/_Layout.cshtml";
which refers to Beer\Views\Shared\_Layout.cshtml, which is:-
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - My ASP.NET Application</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
#RenderBody()
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
</body>
</html>
It then renders in a different font (Helvetica, I suspect). The Visual Studio search and Agent Ransack agree that no source file contains the word "Roman" (it appears in some dlls).
So why is the page being displayed in Times New Roman? Where I should look to find out?
Edit
There are two .css files in the Beer\Content directory. bootstrap.css specifies Helvetica for the body; changing that to Courier and then Times New Roman didn't make any difference. Site.css doesn't mention fonts at all.

why does .net core "Return" verb inside a controller adds "plaintext.css" ?

I was doing some testing with MVC6 .net core, and did a quick hack to return a bootstrap html code by putting dirtyHTML directly inside a controller.
The HTML contains the official example of bootstrap inside a literal string.
Just a quick way of returning some bootstrap html, (as i experiment with controller functionality), to my surprise when i go to a page using a web browser, all html text is shown like plain text, its not rendered.
namespace WebApplication1.Controllers
{
public class MariaController
{
[HttpGet("/index")]
public string index()
{
string dirtyHtml;
dirtyHtml =
#"<!DOCTYPE html>
<html lang=""en"">
<head>
<title>Bootstrap Example</title>
<meta charset=""utf-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1"">
<link rel=""stylesheet"" href=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"">
<script src=""https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js""></script>
<script src=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js""></script>
</head>
<body>
<div class=""container"">
<h1>My First Bootstrap Page</h1>
";
return dirtyHtml;
}
}
When going to debug mode, initially they show the same asci text, but using firefox i see there is a line inserted before my page code:
<HTML><head>
<link rel="alternate stylesheet" type="text/css"
href="resource://gre-resources/plaintext.css"
title="Wrap Long Lines">`
So then i thought, let's look around in the solution and search for "Wrap Long Lines".. as to see where it comes from,... this is however not found.
So where does that come from ? (as the solution doesnt contain plaintext.css either). And more important to me, can it be disabled?.
I am not sure what you want to achive but following thing is way to go.
"Wrap Long Lines" and css related to that are internal to firefox browser.
You are saying that you return html and it display like html but it does not render html and for that do following thing.
[HttpGet("/index")]
public IActionResult index()
{
string dirtyHtml;
dirtyHtml =
#"<!DOCTYPE html>
<html lang=""en"">
<head>
<title>Bootstrap Example</title>
<meta charset=""utf-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1"">
<link rel=""stylesheet"" href=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"">
<script src=""https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js""></script>
<script src=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js""></script>
</head>
<body>
<div class=""container"">
<h1>My First Bootstrap Page</h1>
";
return Content(dirtyHtml,"text/html");
}
See I have return IActionResult and Use Content from return.
Reason for this is when you return string it will display as string and if it is html then it will become encoded as you did not tell browser content type so it consider "text/plain".
An alternative of #dotnetstep's way is using Produces attribute:
[HttpGet("/index")]
[Produces("text/html")]
public string Index()
{
...
}

Partial file not found in mvc application

I am getting following error.
An exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll but was not handled in user code
Additional information: The partial view '../Shared/Partial/_ReferencePartial.cshtml' was not found or no view engine supports the searched locations. The following locations were searched:
I am having login controller in Area/Admin. In Login.cshtml view file, I am referencing Partial View file that contains references to script files. This file is in the folder, Solution/Project/Views/Shared/Partial.
Below is my Login.cshtml view file code.
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>#Messages.Login</title>
#Html.Partial("../Shared/Partial/_ReferencePartial.cshtml")
</head>
...
If you want to load the partial view directly inside the main view you could use the Html.Action helper:
#Html.Action("Load", "Home")
or if you don't want to go through the Load action use the HtmlPartial hepler:
#Html.Partial("_LoadView")
If you want to use Ajax.ActionLink, replace your Html.ActionLink with:
#Ajax.ActionLink(
"load partial view",
"Load",
"Home",
new AjaxOptions { UpdateTargetId = "result" }
)
and of course you need to include a holder in your page where the partial will be displayed:
<div id="result"></div>
Also don't forget to include:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
in your main view in order to enable Ajax.* helpers. And make sure that unobtrusive javascript is enabled in your web.config (it should be by default):
<add key="UnobtrusiveJavaScriptEnabled" value="true" />

Index ActionMethod in Home Controller would be called twice in ASP.Net MVC

i created an ASP mvc 4 project with basic template and just with one Index view .
when i run the application , Index Method that belongs to Home Controller called twice.
i cant understand why
please help me
Thanks Alot
Index Method:
public ActionResult Index()
{
return View();
}
Index View :
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
</body>
</html>
finally i found the problem
i always test my project on google chrome after changing browser and agin run the project on IE it did not occour the problem again
so my browser which was set in VS2012 , and its setting was the problem

how to add script src inside a View when using Layout

I want to include a javascript reference like:
<script src="#Url.Content("~/Scripts/jqueryFoo.js")" type="text/javascript"></script>
If I have a Razor View, what is the proper way to include this without having to add it to the Layout (I only need it in a single specific View, not all of them)
In aspx, we could use content place holders.. I found older examples using aspx in mvc but not Razor view..
Depending how you want to implement it (if there was a specific location you wanted the scripts) you could implement a #section within your _Layout which would enable you to add additional scripts from the view itself, while still retaining structure. e.g.
_Layout
<!DOCTYPE html>
<html>
<head>
<title>...</title>
<script src="#Url.Content("~/Scripts/jquery.min.js")"></script>
#RenderSection("Scripts",false/*required*/)
</head>
<body>
#RenderBody()
</body>
</html>
View
#model MyNamespace.ViewModels.WhateverViewModel
#section Scripts
{
<script src="#Url.Content("~/Scripts/jqueryFoo.js")"></script>
}
Otherwise, what you have is fine. If you don't mind it being "inline" with the view that was output, you can place the <script> declaration within the view.
If you are using Razor view engine then edit the _Layout.cshtml file. Move the #Scripts.Render("~/bundles/jquery") present in footer to the header section and write the javascript / jquery code as you want:
#Scripts.Render("~/bundles/jquery")
<script type="text/javascript">
$(document).ready(function () {
var divLength = $('div').length;
alert(divLength);
});
</script>
You can add the script tags like how we use in the asp.net while doing client side validations like below.
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<script type="text/javascript" src="~/Scripts/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
$(function () {
//Your code
});
</script>
You should add datatable.js script on defer="defer"
<script src="https://cdn.datatables.net/1.10.8/js/jquery.dataTables.min.js" defer="defer"></script>

Resources