Displaying a page in MVC 3 without layout - c#

I have a page that generates a printable table. I need to show this page without my surrounding _Layout page, for printer-friendliness.
How would I go about doing this?

Assuming you use razor view engine (you mentioned layout, not master page)
#{
Layout = null;
}
Well actually you should use razor view engine but anyways, idea is simple. Do not specify (remove) master page file reference in your aspx view and remove all ContentPlaceHolders, write all content directly in page. Or there's another way if you don't wish to remove them for some reason. Make PrintMaster.master master page which will contain nothing but ContentPlaceHolders.

While creating a new view, you can uncheck the use layout checkbox.
This will create you a view with layout as null.
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Test</title>
</head>
<body>
<div>
</div>
</body>
</html>

When you create the view it allows you to change the Master Page. If you unmark the checkbox, the view comes with no Master Page and you can modify the whole page.

If you need to support displaying results on a page as well as having a printable view, you could create a second view (named PrintView for example) that does not use a page layout and call return View("PrintView"); from your controller.

A standard print style action can be done in several ways.
1. use a different view with a print button that sets the layout to null assuming you can map to razor.
To do this with CSS - you will want a separate css file that will be loaded on print and will hide your masterpage items. See the various articles on keywords
css media print
for example:
http://webdesign.about.com/cs/css/a/aa042103a.htm
This uses
<link rel="stylesheet" type="text/css" href="print.css" media="print" />
with the key here being media="print" which will use that css during print only.

Related

Can a view selectively populate sections that appear outside the view in ASP.NET mvc?

I'm making a simple site with bootstrap and .net core mvc (v3.0). Because most of the pages reuse the bootstrap container, I decided to put that in the layout file, so that I wouldn't be repeating the same setup everywhere.
This has the downside that if a view needs fixed elements, those end up getting fixed to the container, not the viewport.
I'm wondering if it's possible to call some sort of syntax inside the view.cshtml file that could cause a section to be rendered in the _Layout.cshtml file (sorry if this has been answered, but I wasn't sure what to search for).
For instance
_Layout.cshtml
#using Microsoft.Extensions.Hosting
#inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment _environment
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"]</title>
</head>
<body>
#* this div only gets rendered based on logic inside the view*#
<div id="conditionalViewDiv">
</div>
<div class="content container-fluid pl-0 pr-0 moveable" id="containerMain">
<main role="main">
#RenderBody()
</main>
</div>
#RenderSection("Scripts", required: false)
</body>
</html>
and then in SomeView.cshtml
#{
ViewData["Title"] = "title";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#MadeUpRenderCommand("conditionalViewDiv")
#*other view stuff*#
Thank you for any help.
According to the docs, View components are intended anywhere you have reusable rendering logic, similar to partial views, but they're much more powerful. The main difference is when you use partial view you still have dependency on controller while in View Component you don't need a controller. So there is a separation of concern.
A view component is a C# class that provides a partial view
with the data that it needs, independently from the parent view and the action that renders it.
Good enlightening examples can be found, particularly:
https://www.c-sharpcorner.com/article/working-with-view-components-in-asp-net-core-mvc/
https://jakeydocs.readthedocs.io/en/latest/mvc/views/view-components.html
Hope this helped.

Show style even that css file is empty

I started to learn mvc, something weird happens, I have index.cshtml and inside of it I have:
<head>
...
<link href="#Url.Content("~/Content/Index.css")" rel="stylesheet" type="text/css" />
</head>
where Index.css is empty file, even that this css file is empty the page gets style, and if I comments the line like:
#*<link href="#Url.Content("~/Content/Index.css")" rel="stylesheet" type="text/css" />*#
then there is no style to the page
Probably you've your Index.css stored in some different location, it could be not visible in Solution Explorer. Try switching to Folder View and search for that css file.
Also it might be stored in bin/obj folder. In that case you can try git clean -fxd.
Probably some stylesheets or bundles are referenced in the _Layout.cshtml.
The _Layout.cshtml is per default the layout for all views so the styles and scripts referenced in it will effect your index.cshtml as well.

Render section inside layout file

I try to understand how works sections in Razor views. I have 2 layout files: _Layout.cshtml and _LayoutChild.cshtml which use the first layout inside. I try to declare sections in _Layout.cshtml and render it in the same file. Markup not appears but when I declare section in _LayoutChild.cshtml everything works. See example below:
_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
#RenderSection("A", false)
</head>
<body>
#section A{
<script>
alert("I'm in Layout!");
</script>
}
</body>
</html>
_LayoutChild.cshtml
#{
Layout = "_Layout";
}
#section A{
<script>
alert("I'm in LayoutChild!");
</script>
}
I understand that declaring section in the same file looks strange but I would like to know why it don't work?
While developing web site or application. Every page have some common section like header, footer, sidebar etc. Write and maintain these on every page is a hard job. So, we need a way to put them in one single place. Luckily in MVC we have Layout concept for this. We put all the common code in it and changing content in Views which will render in layout where we call #RenderBody() method.
Why we need sections ?
Some time we wanted to show specific content on some specific pages like newletters only show on blogs and home page, top news or some advertising banners on specific pages. For these type of scenarios sections rescue us in MVC.
How we can use section ?
We need to follow these two steps to used sections in MVC.
Declare Section in Layout, give it a name and tell is it required on
every page or not.
Define it in view
When views render then section content also added where we declare the section.
Code Example
1. Most of the time we need some specific javascript code for view. So we can do it like this
_Layout.cshtml
#RenderSection("scripts", required: false)
view.cshtml
#section scripts{
<script>
alert("I'm in Layout!");
</script>
}
2. News Letter example
_Layout.cshtml
#RenderSection("newletter", required: false)
view.cshtml
#section newletter{
<h3> New Letter </h3>
... rest of the html ...
}

How to add a media attribute to the CSS LINK html tag for the ASP.NET WebResource.axd Http Handler

The ASP.NET WebResource.axd Http Handler is used to serve resources embedded in DLL's.
The LINK html tag is automatically generated by ASP.NET.
I would like to intercept the generation of the LINK html tag for a certain set of embedded CSS from a third party DLL and add a media attribute.
In summary:
I would like to add a Media attribute to the LINK html tag for the ASP.NET WebResource.axd Http Handler.
So this:
<link type="text/css" rel="stylesheet" href="/WebResource.axd?d=XXXXX" />
Appears like this:
<link media="screen and (min-device-width: 481px)" type="text/css" rel="stylesheet"
href="/WebResource.axd?d=XXXXX" />
Cheers
There is a workaround. Firstly, links like this are being added to the Page's head. Your page must have runat=”server” in the <head> tag for the automatic style sheet inclusion. The pages created by the IDE have this setting automatically. So, links being added is a HtmlLink control type. The idea is to iterate through controls in Page's header, find HtmlLink controls and set necessary attribute (or even attributes). I include this into the Page_Load event:
Page.Header.Controls
.OfType<HtmlLink>()
.ToList()
.ForEach(link =>
{
link.Attributes["media"] = "screen and (min-device-width: 481px)";
});
Before this I had:
<head id="Header">
<title></title>
<link href="App_Themes/MyTheme/main.css"
type="text/css"
rel="stylesheet" />
</head>
and after the result is:
I know, this uses Themes insted of WebResource.axd but for the last one the result will be the same.
The latest thing: there may be another links in the page. So it would be good to recognize our links (the links need to be modified). So if there is no id attribute you could recognize them by href attribute.

Use the same CSS file for masterpage and page content

I have an APS.net app (C#) with several pages that use the same MasterPage. In that page, I have included a couple stylesheets like so:
<head runat="server">
<link href="/apps/_lib/ui/styles1.css" type="text/css" rel="stylesheet" />
<link href="/apps/_lib/ui/styles2.css" type="text/css" rel="stylesheet" />
</head>
These styles apply correctly to all content that is in the actual .master file (page), but are not applied to any pages that use the Master page (for instance default.aspx uses that master page and has a Content placeholder in it).
If I add these lines in each individual page:
<link href="/apps/_lib/ui/styles1.css" type="text/css" rel="stylesheet" />
<link href="/apps/_lib/ui/styles2.css" type="text/css" rel="stylesheet" />
Then the styles show up as expected... but it was my hope that I could include them in the master page so that I didn't need to include these references in each subsequent page too.
Because these files are not located physically in the same project (they are shared between several apps), i cannot just include them as an ASP.net theme that would be applied to all pages.
Update
In order to rule out the file locations problem, I used the absolute URL for these stylesheets...
<link href="https://myserver/apps/_lib/ui/styles1.css" type="text/css" rel="stylesheet" />
<link href="https://myserver/apps/_lib/ui/styles2.css" type="text/css" rel="stylesheet" />
That way, no matter where it is read from, the file can be located. This still exhibits the same behavior.
To me, it looks like the masterPage is rendered with the CSS styles (because they're in the same file) and then the child/calling page is rendered without the CSS styles (because they aren't in that file, they're in the masterPage) and then those two files are combined together (as opposed to combining them together first and THEN rendering the style elements for the combined pages). Adding to this belief was my previous example of adding the include for the CSS file in the calling page itself, which will cause it to display the CSS correctly.
You can view the source of this file, and in the head section, you can see the CSS styles linked correctly, but they aren't applied to any elements from the calling page while they are applied to all elements in the masterPage.
Is the content page in a different folder that the master? If so, you'll have to get the application relative path to the css files using ResolveUrl in the master page:
<link href='<%= ResolveUrl("~/apps/_lib/ui/styles1.css") %>' type="text/css" rel="stylesheet" />
Update: If this doesn't work, then you might have HTML or CSS errors like Lance suggested. Try using the HTML and CSS validators at w3schools.com. If it still doesn't work after fixing any errors, double check your CSS selectors with the rendered HTML as Steve suggested. ASP.Net's generated IDs have bitten me more than once.
What about this?
<link runat="server" href="~/apps/_lib/ui/styles1.css" type="text/css" rel="stylesheet" />
<link runat="server" href="~/apps/_lib/ui/styles2.css" type="text/css" rel="stylesheet" />
What jrummell posted is what I use on my sites to ensure that the links work if I were to move my pages around.
As far as rendering. The rendering is done on the client machine's browser. To the browser it has no idea the html is generated from multiple documents.
I would make sure your HTML and CSS are correct.
On a side note i have noticed the last week or so that VS2008 keeps messing my css stylesheets up, doing really random things like moving text around. However, I think this might just be something on my machine. Just something to check.
Here is some sample code I checked this just to make sure and this works.
Head of Master Page
<head runat="server">
<link rel="stylesheet" type="text/css" href="../css/style.css" />
</head>
Content Place Holder
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div class="something">
Lance
</div>
</asp:Content>
Css in StyleSheet
.something{
color:Blue;
}
The result is "Lance" in Blue in the child page.
Maybe it might be your css selectors. When you add master pages, asp.net tacks on more prefixes to the ids.
I had a similar problem. As others have suggested, you should be able to use ResolveUrl to make sure the path is correct.
Unfortunately, this created a further problem for me. My head tag was runat server. My link tags were not.
The resolve url within my link tag would never execute. Instead, the C# code and response.write tags were being encoded and outputted to the page.
Bizarrely, the same technique in a script (non-runat server) tag would work as normal.
To solve the problem, I ended up writing the whole link tag within an ASP.Net Response.Write tag:
<%="<link href='" + ResolveUrl("~/apps/_lib/ui/styles.css") + "' rel='stylesheet' type='text/css' />"%>
That worked.
How strange. Somehow, it is all related to the head tag being runat sever.
It looks like you have done it correctly, so your error seems weird and sounds like maybe you've mady a typo in the master page. Try to look at the generated source (view source in the browser) of the two pages, one with the links in the master pages and one with the links in the web page, and compare the paths.
Something like this should work. You should be able to include the css in the header of the master. And then, include a ContentPlaceHolder in the header so if you need custom header stuff in your content pages you can do that. Does that not work?
<head>
<link href="/apps/_lib/ui/styles1.css" type="text/css" rel="stylesheet" />
<link href="/apps/_lib/ui/styles2.css" type="text/css" rel="stylesheet" />
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
Ultimately you don't want a
<head></head>
tag in your content page, it's possible that is overriding your master page header.

Categories