Suppose I have the following markup in a standard ASP.NET 2.0 web form:
<head runat="server">
<title>My Snazzy Page</title>
<link type="text/css" href="<%= PathUtilities.AssetPath %>/css/page.css" rel="stylesheet" />
<script type="text/javascript" src="<%=PathUtilities.AssetPath %>/lib/jquery/1.4.2/jquery.min.js"></script>
</head>
What's odd is that this renders the <link> element literally, with the embedded code brackets, while it interpolates the output of the same code into the script tag. In other words, the browser sees this:
<head><title>My Snazzy Page
</title><link type="text/css" href="<%= PathUtilities.AssetPath %>/css/page.css" rel="stylesheet" />
<script type="text/javascript" src="/rmt/lib/jquery/1.4.2/jquery.min.js"></script>
</head>
Obviously the problem disappears if I remove the runat="server" from the head element.
Well what you're doing is (no offence) a bit silly, that is - having a <head> server-side element, with a nested <link> client-side element with server-side href attribute
You are dynamically rendering the href value from server code anyway, so a better solution would be to dynamically render the link tag from the server altogether.
Example (code-behind of page)
// Define an HtmlLink control.
HtmlLink myHtmlLink = new HtmlLink();
myHtmlLink.Href = "/css/page.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);
Your ASPX then becomes much neater:
<head runat="server">
<title>My Snazzy Page</title>
<!-- CSS/JS included dynamically -->
</head>
Related
I'm trying to create razor #section in one of my views, using umbraco:Macro tag, in order to add scripts/styles specific for each view into head tag.
My current code looks like this(head section of master page):
<asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server">
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" type="text/css" href="/css/foundation.min.css">
<script type="text/javascript" src="/js/jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="/js/responsiveslides.js"></script>
<script type="text/javascript" src="/js/js.js"></script>
<umbraco:Macro runat="server" language="cshtml">
#if(IsSectionDefined("JSIncludes"))
{
#RenderSection("JSIncludes")
}
#if(IsSectionDefined("CSSIncludes"))
{
#RenderSection("CSSIncludes")
}
</umbraco:Macro>
</head>
and this(actual section in view):
<asp:Content ContentPlaceHolderId="ContentPlaceHolderDefault" runat="server">
<umbraco:Macro runat="server" language="cshtml">
#section JSIncludes
{
<script type="text/javascript" src="/js/main_page.js"></script>
}
</umbraco:Macro>
But when i'm trying to open a page, i'm getting "Error loading MacroEngine script (file: )" error on top of my page.
Do anyone know the reason of this?
Would be great, if somebody knew how to add things like this properly.
Thanks in advance.
You don't need to use a razor macro to add page-specific script references, use a ContentPlaceHolder
Master page:
<head>
<asp:ContentPlaceHolder ID="PageScripts" runat="server" />
<asp:ContentPlaceHolder ID="PageStyles" runat="server" />
Content page:
<asp:Content ID="PageScript" runat="server" ContentPlaceHolderID="PageScripts">
<script type="text/javascript" src="/js/main_page.js"></script>
</asp:Content>
Reference
(I have tested this with a vanilla asp.net site running from the webdev server and it is a problem here also):
I have the following markup in my .master file
<!DOCTYPE html>
<html>
<head runat="server">
<link href="/Styles/Site.css" rel="stylesheet" type="text/css" />
<link rel="alternate" type="application/rss+xml" title="rss" href="/Pages/Static/Feed.aspx?type=rss&lang=en" />
</head>
the rendered html comes out like this:
<!DOCTYPE html>
<html>
<head>
<link href="/Styles/Site.css" rel="stylesheet" type="text/css" />
<link rel="alternate" type="application/rss+xml" title="asdsad" href="/Pages/Static/Feed.aspx?type=rss&lang=en" />
</head>
(the rss link "&" has been encoded to "&")
however if i change the markup to
<!DOCTYPE html>
<html>
<head>
<link href="/Styles/Site.css" rel="stylesheet" type="text/css" />
<link rel="alternate" type="application/rss+xml" title="rss" href="/Pages/Static/Feed.aspx?type=rss&lang=en" />
</head>
(no runat="server" on the head tag)
then the resulting html comes out as expected:
<!DOCTYPE html>
<html>
<head runat="server">
<link href="/Styles/Site.css" rel="stylesheet" type="text/css" />
<link rel="alternate" type="application/rss+xml" title="rss" href="/Pages/Static/Feed.aspx?type=rss&lang=en" />
</head>
Clearly Asp.Net does something to encode the url. As it happens, I really need the head tag to be runat="server" and I would also like to be able to have "&" in link-urls within it is there some trick I can use to have my cake and eat it too?
Yours
Andreas
This issue happened to me before, I couldn't find out the reason for this, I ended up putting a literal inside the head, and filled the html from the code behind.
html:
<head runat="server">
<asp:Literal runat="server" ID='litLinks' />
</head>
C# code:
protected void Page_Load(object sender, EventArgs e)
{
litLinks.Text = "<link rel='alternate' type='application/rss+xml' title='rss' href='/Pages/Static/Feed.aspx?type=rss&lang=en' />"
+ "<link href='/Styles/Site.css' rel='stylesheet' type='text/css' />";
}
Note: If you're going to downvote, explain why, because nothing I have said is wrong, unless you otherwise prove so.
You're meant to escape ampersands in url's since putting a non-escaped ampersand in a url, the browser expects there to be something encoded. By escaping it, your telling the browser exactly what it is, an ampersand.
It doesn't break your links and is valid.
Also if you wanted to pass an actual ampersand in a url that isn't defining a new querystring paramter, then you would url encode the ampersand to be '%26'
Edit: Since you're probably using this in some really weird way. Here's the why, it's correct for ASP.Net to HTML Encode the ampersand for the HTML document.
When the browser issues a request for the URL, it doesn't send a request for the HTML encoded URL, it sends a request for the non-HTML encoded URL.
If for some reason you're accessing the value server-side or something, then you can do something like:
var url = new Uri(HttpUtility.HtmlDecode(#"http://www.google.com/somepage.aspx?key1=value1&key2=value2"));
var query = HttpUtility.ParseQueryString(url.Query);
var result = query["key2"];
Console.WriteLine(result);
So you decode the HTML version of the link first, parse it as a Uri, get the querystring from it and key your key/value collection.
I'm trying to use the Response.Write() method to dynamically insert content in the < head > section of an aspx page. I need to inject a string value from a property on a code-behind object which is a link to my CSS file. However, it is not being processed properly at run time. The object is public on the class and is hydrated in the Page_Load() event. Down in the body of the page I can successfully inject other properties from the Corpoartion object with no problem at all.
Why does this not work in the < head > section?
This is the part that does not expand correctly:
<link href="<%= Corporation.PageStyleSheet %>" rel="stylesheet" type="text/css" />
Here is the entire < head > section:
<head runat="server">
<title></title>
<link href="<%= Corporation.PageStyleSheet %>" rel="stylesheet" type="text/css" />
<script language="JavaScript" type="text/JavaScript" src="cntv_menu.js"></script>
<script language="JavaScript" type="text/JavaScript" src="cntv_category.js"></script>
</head>
What is the reason that this will not expand properly?
You can't use <%= %> inside a runat="server" tag, which your <head> tag is.
You can either change it to <%# %> and DataBind to it in the code-behind, or you can make the link tag runat="server", give it an id and assign the attribute from the code behind.
See this answer, which goes into the details.
Use this:
this.myButton.Attributes.Add(attribute, value);
It worked for me :)
the best way to resolve this problem is using OnPreRender
Example:
First, define your tag:
<link href="~/css/your_default.css" type="text/css" runat="server" id="myCSS" />
And on the OnPreRender:
protected override void OnPreRender(EventArgs e){
base.OnPreRender(e);
myCSS.Attributes["href"] = "~/css/your_new.css";
}
If you write out the full line you should be ok:
<%
Response.write("<link href=\"" + Corporation.PageStyleSheet + "\" rel=\"stylesheet\" />");
%>
P.S. My syntax may not be completely right, sorry in advance.
In my view, I have included the Master page as follows:
<%# Page Title=""
Language="C#" MasterPageFile="~/Views/Shared/Mall.Master"
Inherits="System.Web.Mvc.ViewPage<DomainModel.Entities.Seller>" %>
And in my Mall.master file, I add a link to include a general css file
<link rel="Stylesheet" href="../../Content/MallMaster.css" type="text/css" />
However, I need another more specific purpose css file CheckOut.css in my view. Since the style defined in Checkout.css only applies for one page, I do not want to include the file in the master page. Is there any way to include the file in my view?
You should add a new content () placeholder in your MasterPage and then in your view you can add another css to this placeholder.
<asp:ContentPlaceHolder ID="head" runat="server">
<title></title>
<link rel="Stylesheet" href="../../Content/MallMaster.css" type="text/css" />
</asp:ContentPlaceHolder>
This may be helpful for you - How to pass page’s meta tags in ASP.NET MVC?
If you don't want to override existing tags in the master, you can add a content placeholder inside the head tag too:
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="title" runat="server">
Default Title</asp:ContentPlaceHolder>
</title>
<!-- The ContentPlaceHolder is placed inside the title tag to make sure that the
document validates in the VS editor - <title> needs to be a direct child of
<head>. The output will validate. -->
<script src="theAllFamous_jQuery.js" type="text/javascript" />
<link href="sitewide.css" type="text/css" rel="Stylesheet" />
<asp:ContentPlaceHolder ID="headContent" runat="server />
</head>
And in your view:
<asp:Content ID="title" ContendPlaceHolderId="title" runat="server">
Page specific title
</asp:Content>
<asp:Content ID="head" ContentPlaceHolderId="headContent" runat="server">
<link href="pagespecific.css" type="text/css/ rel="Stylesheet" />
</asp:Content>
That way you won't have to duplicate code that you want in all head tags on your site.
I know I can access the head section of a page which uses a masterpage programmatically this way (in code behind):
This is only an example (I'd like to insert scripts and styles etc.):
this.Header.Title = "I just set the page's title";
Is there a simple way to do this in a declarative way on in the aspx file itself?
Sometimes it would be handy to insert a client script or a style declaration or a link to an external resource.
You can do this by using content regions in the head, in exactly the same way as you would in the body of the page. eg, In your masterpage:
<head>
<link type="text/css" rel="stylesheet" href="/styles/common1.css" />
<script type="text/javascript" src="/scripts/common1.js"></script>
<asp:contentplaceholder id="ExtraStylesAndScripts" runat="server" />
</head>
And then in the page itself just something like:
<asp:content contentplaceholderid="ExtraStylesAndScripts" runat="server">
<link type="text/css" rel="stylesheet" href="/styles/extra1.css" />
<link type="text/css" rel="stylesheet" href="/styles/extra2.css" />
<script type="text/javascript" src="/scripts/extra1.js"></script>
<script type="text/javascript" src="/scripts/extra2.js"></script>
</asp:content>
For stylesheet you can use this :
HtmlLink cssRef = new HtmlLink();
cssRef.Href = "addins/main.css";
cssRef.Attributes["rel"] = "stylesheet";
cssRef.Attributes["type"] = "text/css";
Page.Header.Controls.Add(cssRef);
For Meta Tags :
HtmlMeta metaTag = new HtmlMeta();
metaTag.Name = "author";
metaTag.Content = "ScarletGarden";
Page.Header.Controls.Add(metaTag);
But there is no way to add external script files to header element.
You can add inside body element by :
if (!ClientScript.IsClientScriptIncludeRegistered("myExternalScript"))
{
ClientScript.RegisterClientScriptInclude("myExternalScript", "js/myJSFile.js");
}
Hope this helps !
You can declare the page title in the content page declaration.
<%# Title="Page Title" Page Language="C#" AutoEventWireup="true" CodeFile="Subpage.aspx.cs" Inherits="Subpage" MasterPageFile="~/MasterPage.master" %>
I haven't tried this.
But you can put HEAD element inside html with the enclosed string in asp style markup.
e.g.
<%=myTitle%>