Referencing favicon from inside folder using ASP.Net master page and themes - asp.net

I have the following situation on my new ASP.Net page:
I am using a master page
I am using themes
I have pages in separate folders
I need to reference a favicon from my master page based on the current theme.
Unfortunately the ~App_Themes/Basic/Images/favicon.ico path resolves to http://example.com/folder/App_Themes/Basic/Images/favicon.ico.
How can I uniformly refer to my favicon.ico located in the App_Themes/Basic/Images/favicon.ico path from master page used by the following differently located pages:
~/Home.aspx
~/Secure/Dashboard.aspx
~/Accounts/Login.aspx

Usually ASP.NET themes are limited to skin files and CSS files with all images referenced from the CSS file. In that scenario, the paths to images are relative from the CSS file.
If you need a path to a file inside the current theme's folder relative from a page, you can use the Page.Theme property combined with the Page.ResolveUrl() method:
<%= Page.ResolveUrl(String.Format("~/App_Themes/{0}/Images/favicon.ico", Page.Theme)) %>
If you want to use that in a <link rel="shortcut icon"> element you can just put the code above inside the href attribute. Unless you have a <head runat="server">, in which case ASP.NET may throw an HttpException:
The Controls collection cannot be modified because the control
contains code blocks (i.e. <% ... %>).
This can be fixed by putting the <link> element inside an <asp:PlaceHolder> control:
<head runat="server">
<asp:PlaceHolder runat="server">
<link rel="shortcut icon" href="<%= ... %>" />
</asp:PlaceHolder>
</head>

Related

User Control with external CSS file

I have an ASCX user control in the root of my Web application. It references a stylesheet, something like
<link type="text/css" rel="stylesheet" href="MyStyle.css" />
The problem is if any ASPX pages located in application subfolders reference that user control - they don't see the stylesheet, because href path is relative and stylesheet remains in the app root.
Is there a way besides copying the CSS into all the subfolders to universally reference it from the root? I have no problem referencing external JavaScript, using ScriptManagerProxy I can specify path to external JS file via ASP.NET "~/" notation which gets resolved into real path from any location. Does something similar exist for CSS?
ResolveUrl will convert application-relative urls for you. http://msdn.microsoft.com/en-us/library/system.web.ui.control.resolveurl.aspx
<link href="<%= ResolveUrl("~/MyStyle.css") %>" rel="stylesheet" />
EDIT: If you don't want to use inline code blocks
code-behind
protected void Page_Load(object sender, EventArgs e)
{
litStyle.Text = string.Format("<link href=\"{0}\" rel=\"stylesheet\" />", ResolveUrl("~/MyStyle.css"))
}
markup
<asp:Literal ID="litStyle" runat="server"/>
As I mentioned in my comments I didn't want to use <%= %> blocks. But I didn't want to assign URL of CSS file in code-behind either, so I found a compromise. I declare <link> tag with runat="server" attribute and ASP.NET - style href:
<link rel="stylesheet" type="text/css" runat="server" id="xlinkCSS" href="~/MyStyle.CSS" />
and then in code-behind simple resolve that link
xlinkCSS.Attributes("href") = ResolveUrl(xlinkCSS.Attributes("href"))
Using this approach ultimately I can create a function that accepts page as a parameter, loops thru all "link" tags, resolving their URLs.
Actually you have two options:
1- to include it in your themes folder, then the asp.net framework will automatically include it in all pages using this theme
2- to add a public variable in your CS code that includes the path, then to use it in your code, as the following code:
public string basepath = "http://" + Request.Url.Authority + Request.ApplicationPath;
then to use it in ASP code:
<link type="text/css" rel="stylesheet" href="<%=basepath %>MyStyle.css" />
You should make bundle.config file and then you can use this in your code

Referencing CSS Sheet in Aspx page with Master Page

Question is pretty well stated in the title. Normally I would use <link... /> to reference my CSS Sheet but since I'm using a master page I don't have access to the Head Tag so how do I reference a specific CSS sheet on my ASPX page. I tried using <%# Import Namespace="Style.css" but no luck. Thanks for the help.
Just add a CSS ContentPlaceHolder with a default value in it.
Basically, the CSS file you specify as default will be included unless you override that placeholder with an tag from a child page.
Your Master Page should look something like this.
<head>
<asp:ContentPlaceHolder ID="Stylesheets" runat="server">
<link rel="stylesheet" href="/css/master.css" type="text/css" />
</asp:ContentPlaceHolder>
</head>
Then from any pages using that Master Page, you can simply override that with a different stylesheet.
On (example) AboutUs.aspx
<asp:Content ID="Content1" ContentPlaceHolderID="Stylesheets" runat="server">
<link rel="stylesheet" href="/css/Style.css" type="text/css" />
</asp:Content>
If you want to add a CSS stylesheet to any ASPX page, you should use PlaceHolders.
Master page: (in the section)
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
ASPX Page:
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
// add your link here
</asp:Content>
just drag your style sheet to your master page.aspx and it will work for all your other forms
You have 3 possible solutions:
Add your link to the head tag of the master page's markup. If you do so, all the pages using the given master page will automatically use your css file.
Use a ContentPlaceHolder in the head tag of your master page. You can use the ContentPlaceHolder at your pages referencing the given master page and you can add your link tag inside the ContentPlaceHolder tag in the markup.
You can add your link tag using Javascrip/jQuery functions.
Although I went the code behind route below in my Page_Load event (VB), I'll give the correct answer to A.K as it seemed to answer the question better but just didn't suit my specific case.
Dim link As New HtmlLink()
link.Attributes.Add("href", Page.ResolveClientUrl("../Css/Generic-Form2.css"))
link.Attributes.Add("Type", "text/css")
link.Attributes.Add("rel", "stylesheet")
Page.Header.Controls.Add(link)
Append the link tag to the head using DOM manipulation.

Understanding the runat server attribute

I'm really new to ASP.NET. I was just checking out a default ASP.NET web application. It comes by default with a few pages (Default.aspx, About.aspx etc).
I noticed that the Site.master file is the file where i create the main layout for my pages.
But i also noticed that the head tag has a runat="server" attribute.
I know this tag is used in <asp:XXX> tags, but why in a <head> tag???
Also, when i remove that attribute, then all of the styles are gone from the webpage. So appearently it's doing something. I just don't understand what its exactly doing...
So why is it there, on an HTML tag...??? I don't see any code in there that should be run on the server...
<head runat="server">
<title>Hallo</title>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<!-- This part is run on the server. So why does the head tag
also need a runat=server ?? -->
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
You asked why the styles are not applied anymore when removing the runat="server" from the<head> element.
It is simple: by running on the server side, the parser will replace the ~/ from the stylesheet declaration <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" /> with the root path of the application.
The ~ is illegal in a URL. Thus, if this is not replaced by the parser, the file will not be found thus the stylesheet will not be applied.
Oh, btw, setting the runat="server" attribute on the <head> element will force all its sub-elements to be run on the server, thus why the <link> element is run on the server.
The head element contains a runat="server" attribute, which indicates that it is a server control (rather than static HTML). All ASP.NET pages derive from the Page class, which is located in the System.Web.UI namespace. This class contains a Header property that provides access to the page's region. Using the Header property we can set an ASP.NET page's title or add additional markup to the rendered section. It is possible, then, to customize a content page's element by writing a bit of code in the page's Page_Load event handler.
' Programmatically add a <meta> element to the Header
Dim keywords As New HtmlMeta()
keywords.Name = "keywords"
keywords.Content = "master page,asp.net,tutorial"
Page.Header.Controls.Add(keywords)
For more info see Specifying Meta Tags in ASP.NET with VB.NET.
The runat="server" tag in ASP.NET allows the ability to convert/treat most any HTML element as a server-side control that you can manipulate via code at generation time. Some controls have explicit implementations, others simply revert to a generic control implementation.
The runat attribute basically tells ASP.Net that it needs to parse the element, its attributes and it's contents as a server control. Enabling code, on the server, to be executed to configure the response.
Without it, any child controls contained within the <head> section will not get parsed. So, any dynamic header includes, title manipulations or any other server-controls will not be interpreted.

Prevent ASP.NET themes from auto-adding CSS files

Having to deal with URL rewriting, I decided to programmatically add CSS references rather than relying on the automatic behavior of ASP.NET to add all CSS files within a theme automatically to the <head> of an ASPX page.
I suceeded in adding the CSS file programmatically by using
<link type="text/css" rel="stylesheet" runat="server" id="CssFile" />
and setting the actual URL it in code behind.
My question is:
Is there a way to prevent the ASP.NET "engine" from automatically adding all CSS files into the <head> of my ASPX/master page?
(Of course, I still could go with my own folders and completely drop the App_Themes concept)
You can prevent this feature by adding the following attributes to the Page directive:
<%# Page ... EnableTheming="false" Theme="" StylesheetTheme="" %>
I do not believe you can tell a skin to not include the files within it, that was the killer for us when it came to using them as it referenced all the css files not just the ones we needed and we needed maximum efficiency.
<head runat="server" visible="false" />
<%# Master Language="C#" AutoEventWireup="true" Inherits="Front" Codebehind="Front.master.cs" **EnableTheming="false"** %>
was my solution to getting around the problem.

Do script tags and link tags go inside asp:content or outside

I have a page which has a masterpage. Do I put script and link tags inside the asp:content place holders or outside or does it matter.
When I put it outside, I get the following warning:
Only Content controls are allowed directly in a content page that contains Content controls.
I can see five (or 8) ways of doing it:
In the codebehind (.cs or .vb) using:
Scriptmanager.RegisterClientScriptinclude - using an absolute/relative path
Scriptmanager.RegisterClientScriptInclude - using an embedded resource
Scriptmanager.RegisterSlientScriptBlock - with your source inside
Adding it inline to your ASPX page in the designer
Sticking it inside the asp:content where the content lives inside the body tag.
Sticking it inside the asp:content where the content lives inside the head (You've said this isn't an option, so ignore this).
Adding it programmatically using the ScriptManager inside a control you use on the page as above.
"Only Content controls are allowed directly in a content page that contains Content controls" - did you forget the runat="server"?
If it's scripts and links for all pages, it should go outside any ContentPlaceHolders. If it's scripts and links for this page, it should go inside a Content inside the head. If it's default scripts, put it inside a head ContentPlaceHolder, and it can be replaced by the child page if needed. (VS usually complains about a ContentPlaceHolder in the head, but it works fine for me).
// master Page
<head runat="server">
<asp:ContentPlaceHolder id="head" runat="server">
<!-- Default scripts and CSS -->
<link rel="stylesheet" type="text/css" href="default.css" />
<script type="text/javascript" src="jquery.js"></script>
</asp:ContentPlaceHolder>
<!-- Mandatory scripts and css -->
<link rel="stylesheet" type="text/css" href="all.css" />
<script type="text/javascript" src="all.js"></script>
</head>
<body>
Master Page!
<asp:ContentPlaceHolder id="body" runat="server" />
</body>
// Child (no JQuery)
<asp:Content ContentPlaceHolderID="head" runat="server">
<link rel="stylesheet" type="text/css" href="default.css" />
<!-- Don't need JQuery -->
<script type="text/javascript" src="prototype.js"></script>
</asp:Content>
<asp:Content ContentPlaceHolderID="body" runat="server">
Child Page!
</asp:Content>
// Child 2 (with JQuery)
<asp:Content ContentPlaceHolderID="body" runat="server">
Child Page!
</asp:Content>
If you are referring to <asp:Content /> tags, you can't put anything outside of them in an .aspx page. So you're limited to putting them inside the <asp:Content /> tag. If you want <script /> and <link /> tags you need to either put a <asp:ContentPlaceHolder /> in the <head> of your master page, or add them dynamically via the Page's Controls collection.
Outside. Tthe inside of the ContentPlaceholders is going to be replaced with content from your pages anyhow so it doesn't make much sense to put anything in there.
outside. in the master page
The place holders are the wrapping controls for pages which descend from master pages.
Use asp.net scriptreference tag in master page to add reference to javascript file and you will be able to access all you need in the javascript file as if you would have added to the local page.

Resources