I was advised (by a person I cannot now contact to ask this) to use a query-string-trick to keep from caching a style sheet while I was debugging. The respondent said this would do the trick:
#{ var currentDate = DateTime.Now; }
<link href="#Url.Content("~/Styles/Site.css?" + currentDate)" rel="stylesheet" type="text/css" />
And I see why, but the expression #{ var currentDate = DateTime.Now; } is just resolving to the literal value in the page when I run it. The full code is:
<head runat="server">
<title></title>
#{ var currentDate = DateTime.Now; }
<link href="#Url.Content("~/Styles/Site.css?" + currentDate)" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
The syntax "#{ }" is new to me. I don't see a reference to it in any doc that I have looked at. According to the usage it appears to be inline script, but it isn't being treated as that at runtime, and I am not even sure if it is Active Server Page syntax (or PHP?).
What DOES work is:
<% var currentDate = DateTime.Now; %>
<link href="~/Styles/Site.css?<%= currentDate%>" rel="stylesheet" type="text/css" />
OK, but still, what does "#{ <some expression> }" signify?
It's Razor, which is a newer rendering engine for asp.net. It's doing the exact same thing as your <% %> block of code.
It is not an expression, it is a code block (a collection of one or more declarations and statements) in Razor syntax.
The reason it does not work for you is that you are not using the razor engine. # replaces the need for <% %> in asp.net by implementing the Razor engine, most notably through mvc3.
Related
I need to add the version at each css file, for that I have created a function which returns the build version, but when I add the function to the path it doesn't get properly rendered:
<!--Code-->
<link href="Styles/Site.css<% Version() %>" rel="stylesheet" type="text/css" />
<!--Render-->
<link href="Styles/Site.css<% Version() %>" rel="stylesheet" type="text/css" />
I tried both <% %> and <%= %> and even using a global variable instead of a public function but with no results, however I was able to add the version to js files through modifyng the path in the ScriptManager object.
You can always add a stylesheet programatically.
HtmlLink hl = new HtmlLink();
hl.Href = "Styles/Site.css" + Version();
hl.Attributes.Add("type", "text/css");
hl.Attributes.Add("rel", "stylesheet");
Page.Header.Controls.Add(hl);
The reason <%= %> does not work is because it is in the Head of the page, which is a Control in itself. If you put your sheet outside the Head, it does work.
I write it in aspx like this:
<link type="text/css" href='/theme<%=theme%>/top.css' rel="stylesheet" />
but result is this:
<link type="text/css" href="/theme<%=theme%>/top.css" rel="stylesheet" />
surprising is that using in js is no problem.
It's because your link is inside a <head> tag which is runat server. The head tag is "smart", in that when it sees a <link> tag it lets you actually use the application relative path syntax: ~/. So if you do (inside your head tag):
<link href="~/Content/Site.css" rel="stylesheet" />
You'll see it will actually work (that is, it will expand the tilde to the proper location of your site), even though nowhere did you say runat server. The downside of course is when you DON'T want it to do that. :) Probably the easiest solution is to just manually build the tag yourself like this:
<%= "<link type=\"text/css\" href='/theme" + theme + "/top.css' rel=\"stylesheet\" />" %>
You can't use expressions with <head runat="server"> instead you have to write following code in Page_Load event to insert <link/>
HtmlLink link = new HtmlLink();
link.Attributes.Add("type", "text/css");
link.Attributes.Add("rel", "Stylesheet");
link.Attributes.Add("href", "/theme" + theme + "/top.css");
Header.Controls.Add(link);
The project I'm working on allows an end-user to modify CSS code to integrate the application as best possible. Most of the CSS values are stored in a database and need to be retrieved and parsed dynamically.
I setup a Style controller, and gave each stylesheet an action, and then passed the configuration data through to the View. I set the ContentType to "text/css" and then generated the stylesheets.
This works fine, but the problem I'm running into is this: none of the code works in the application. I include it in the head code, but it doesn't parse in the code.
An example of what I do is this:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" ContentType="text/css" %>
.element {
background-color: <%= ViewData.Model.BackgroundColor %>;
}
I include it like so:
<link href="/style/Basic" rel="stylesheet" type="text/css" media="all" />
When I include the CSS code in a partial view and include it using the ViewModel (wrapped in style tags) in an action, then everything works fine. It is when I try to parse this as a separate file when it does not work.
Is there something I am doing incorrectly? Or is there some kind of glitch?
Thanks in advance :D
Use a tool such as HTTPWatch to verify that the stylesheet is being sent down and not 404'd
Controller
public ActionResult Basic()
{
Response.ContentType = "text/css";
var basicVM = new BasicVM()
{
BackgroundColor = "Lime",
};
return View(basicVM);
}
And the View
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MvcApplication3.Controllers.BasicVM>" ContentType="text/css" %>
body {
background-color: <%= ViewData.Model.BackgroundColor %>;
}
and the test page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Test</title>
<link href="/Home/Basic" rel="stylesheet" type="text/css" media="all" />
</head>
<body>
<div>
Test
</div>
</body>
</html>
Turns everything Green
Example 1:
<head>
<meta http-equiv="description" content="<%= Foo %>"/>
</head>
Renders
<meta http-equiv="description" content="Bar"/>
Example 2:
<head runat="server">
<meta http-equiv="description" content="<%= Foo %>"/>
</head>
Renders:
<meta http-equiv="description" content="<%= Foo %>"/>
Note the discrepancy, the < has become < but the > remains the same.
There are some questions on this topic, and the answers are the workarounds, but nobody seems to know why this happens.
You can't have a script tag (<% = %>) inside a server control, that's why it's turned into plain text instead of being executed.
You can add the meta tag from the code behind like this:
HtmlMeta meta = new HtmlMeta();
meta.HttpEquiv = "description";
meta.Content = Foo;
Page.Header.Controls.Add(meta);
When you add runat=server the Head tag becomes a server control. I guess based on your results that the contents of server controls are not parsed for inline substitutions using the <% ... %> syntax.
You could make the Meta tag a server control as well by adding the runat=server to it and access its attributes programmatically.
I'm in the process of deploying an ASP.NET MVC app to IIS 6, but am running into an issue with the root path.
In Global.asax, I have the root path mapped:
routes.MapRoute("Root", "",
new { controller = "Dashboard", action = "Index", id = "" });
When I navigate to http://servername:70/test2/, the app displays the right page, but the stylesheet and JavaScript files are not loading. Looking at the source, the paths are showing like this:
<script src="test2/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css"
href="test2/Content/stylesheets/app.css" />
Which makes the browser look for
http://servername:70/test2/test2/Content/stylesheets/app.css
When I go directly to a controller (http://servername:70/test2/Dashboard.aspx), the paths are correct:
<link rel="stylesheet" type="text/css" href="Content/stylesheets/app.css" />
This is also occurring with any links generated with ActionLink. The stylesheet and script paths are being generated with Url.Content:
<link rel="stylesheet" type="text/css"
href="<%= Url.Content("~/Content/stylesheets/app.css") %>" />
I have recently answered a question similar to this which uses Rob Conery's Script Registration Helper. I'll copy the answer in here for you, and add an example HtmlHelper for stylesheets.
public static string RegisterJS(this System.Web.Mvc.HtmlHelper helper, string scriptLib) {
//get the directory where the scripts are
string scriptRoot = VirtualPathUtility.ToAbsolute("~/Scripts");
string scriptFormat="<script src=\"{0}/{1}\" type=\"text/javascript\"></script>\r\n";
return string.Format(scriptFormat,scriptRoot,scriptLib);
}
public static string RegisterCSS(this System.Web.Mvc.HtmlHelper helper, string styleLink, string rel) {
//get the directory where the css is
string stylesheetRoot = VirtualPathUtility.ToAbsolute("~/Content/Stylesheets");
string styleFormat="<link type='text/css' href='{0}/{1}' rel='{1}' />\r\n";
return string.Format(styleFormat, stylesheetRoot, styleLink, rel);
}
Usage:
<%= Html.RegisterJS("myscriptFile.js") %>
<%= Html.RegisterCSS("app.css") %>
Hope this helps.
Also, I note that there was another response on that question by Levi:
This should have been fixed in RC2. If you are using RC2 and are still seeing this problem, please file a bug at http://forums.asp.net/1146.aspx.
If this is your preferred answer, the please upvote Levi's response.
Or, use the Url.Content ...
<link href="<%=Url.Content("~/Content/Site.css") %>" rel="stylesheet" type="text/css" />