User Control with external CSS file - asp.net

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

Related

Why does MVC automatically expand virtual URLs?

In my Layout.cshtml file I have the following line:
<link rel="stylesheet" href="~/Content/bootstrap.css" />
My assumption was that since I did not include Url.Content() call, it would actually just render what I wrote but not expand the virtual URL automatically. This assumption is wrong - the generated HTML does include the correct path to the file, not the virtual path I entered.
If I wrap the <link> in <script>
<script type="text/html">
<link rel="stylesheet" href="~/Content/bootstrap.css" />
</script>
then the URL is not expanded.
Which part of ASP.NET MVC does this automatic parsing of HTML and is there a way to control it?
This was a new feature included in Razor2 and ASP.NET MVC 4 and was designed to make life easier by not having to use Url.Content everywhere.
http://www.davidhayden.me/blog/asp.net-mvc-4-the-new-tilde-slash-feature-in-razor-2
The feature only works inside standard HTML attributes and that's why you don't get it inside your <script> tag or anywhere else.
You could use a simple output write to work around this:
<link rel="stylesheet" href="#("~/Content/bootstrap.css")" />

Referencing External Files from ASP.NET Web Control?

What is the preferred method to reference external files from my ASP.NET web control?
My web control needs to access two external files. One is a CSS file. The other is a JavaScript file.
<link href="<%= VirtualPathUtility.ToAbsolute("~/css/mycss.css") %>" rel="stylesheet" type="text/css" />
<script src="<%= VirtualPathUtility.ToAbsolute("~/scripts/myjs.js") %>" type="text/javascript"></script>
The page could potentially contain multiple instances of my control. Of course, I only want the page to include a single reference to each file.
I looked at the Page.ClientScript properties and methods. But it doesn't appear to have one specifically for CSS.
I also looked at using something like Page.Header.Controls.Add(link), but this doesn't appear to have direct support for preventing multiple references to the same file.
Is there another option?
Okay, so apparently there is no preferred method for this:
The following seems to be working:
if (!Page.ClientScript.IsClientScriptIncludeRegistered("MyControl.ascx.cs"))
{
Page.ClientScript.RegisterClientScriptInclude("MyControl.ascx.cs", ResolveClientUrl("~/scripts/myjs.js"));
HtmlHead head = (HtmlHead)Page.Header;
HtmlLink link = new HtmlLink();
link.Attributes.Add("href", "~/css/mycss.css");
link.Attributes.Add("type", "text/css");
link.Attributes.Add("rel", "stylesheet");
head.Controls.Add(link);
}

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

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>

Implementing CSS as a variable in the site.master page in ASP.NET MVC3

I am implementing a web application using ASP.NET MVC3. In the application I want to add the option of switching between CSS files (for themes) based on clicking some links. I did some research and I came up with the following:
To pass data to site.master, the good solution is to create an abstract controller and inherit that into the other controllers that have site.master as their template, according to this article: Passing Data to View Master Pages
I can pass a viewbag message to the link which controls the css file URL to set the current css file to use, based on the code that I am seeing being passed to scripts at the top of the site.master page:
script src="<%: Url.Content("~/Scripts/jquery-1.5.1.min.js") %>" type="text/javascript"
So I created an abstract controller, ApplicationController, with the following method:
public ApplicationController()
{ViewBag.NewMessage = "../../Content/Site2.css";}
And in the site.master, I included this link:
<link href="<%: (string) ViewBag.NewMessage %>" rel="stylesheet" type="text/css" />
However, that doesn't seem to be working, as it is being interpreted as:
<link href="<%: (string) ViewBag.NewMessage %>" rel="stylesheet" type="text/css" />
And only when I remove the quotation marks:
<link href=<%: (string) ViewBag.NewMessage %> rel="stylesheet" type="text/css" />
is it being interpreted correctly (and the webpage gets rendered with the correct css), except that it violates html standards:
<link href=../../Content/Site2.css rel="stylesheet" type="text/css" />
Any suggestion about how to go tackling this problem or is there a more elegant solution I'm missing? I was going to proceed and implement variables in the ApplicationController that get selected based on links the user clicks at the top of the page, to switch between css styles.
Thank you!
Check to make sure your <head> tag does not have runat="server".
After making this change, be sure to check your script and css tags. This change can break the paths if you use the ~/ to ref app root. To help with this, use the Url.Content(...) helper.

In ASP.NET Webforms, how do get my control to work in a link tag's href attribute?

I have a situation where I need to dynamically load a URL prefix.
I wrote a quick control to handle this and it works for the following instance:
<script type="text/javascript" src='<gbn:AdminPath runat="server" id="Id1" />Rest/Of/Path.js'></script>
But the following case (on the same aspx page) does not work:
<link rel="stylesheet" href='<gbn:AdminPath runat="server" id="Id2" />/css/styles.css'>
This shows up in the browser as:
<link rel="stylesheet" href="<gbn:AdminPath runat="server" id="Id2" />/css/styles.css" />
I've tried various things, but I can't seem to get the tags working. Any suggestions?
Thanks
The problem here is that it treats <link> elements in the <head> section like they are server controls. It does this, I believe, so that you can use app-relative urls (eg "~/myfolder/file.css") and have them resolved for you. It does not give this same treatment to <script> tags, though.
Since they are treated as server controls, you cannot mix inline script and string literals in a property value or it all gets treated as a literal (as you discovered).
To get around this, you have several options, one of which TheGeekYouNeed outline above.
If you still want to do it inline with a public method, you can, but you have to build the whole property value in your code like the following:
<link rel="stylesheet" href='<%= string.Format("{0}/css/styles.css", GetAdminPath() %>' type="text/css" />
Add the in the code behind
example:
// Define an HtmlLink control.
HtmlLink myHtmlLink = new HtmlLink();
myHtmlLink.Href = GetAdminPath() + "/pathtocss.css";
myHtmlLink.Attributes.Add("rel", "stylesheet");
myHtmlLink.Attributes.Add("type", "text/css");
// Add the HtmlLink to the Head section of the page.
Page.Header.Controls.Add(myHtmlLink);

Resources