可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
For some reason by css link in a webforms master page is getting mangled by ASP.NET.
The page using the masterpage is located in /subdir1/subdir2/page.aspx
Not sure why it is happening but here is a snippet of the code:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<link href="<%= MyNamespace.Helpers.UrlHelper.CssRoot %>Site.css" rel="stylesheet" type="text/css" />
<script src="<%= MyNamespace.Helpers.UrlHelper.JavascriptRoot %>jquery-1.3.2.min.js" type="text/javascript"></script>
<asp:ContentPlaceHolder ID="cphHead" runat="server">
</asp:ContentPlaceHolder>
</head>
The Html output that is being created is:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
Untitled Page
</title><link href="../../%3C%25=%MyNamespace.Helpers.UrlHelper.CssRoot%20%25%3ESite.css" rel="stylesheet" type="text/css" />
<script src="/Javascript/jquery-1.3.2.min.js" type="text/javascript"></script>
</head>
Why is this working for the script tag but mangling the link tag and not actually executing the code included. If I change the 'link' tag to be a 'script' tag (which is wrong but for testing purposes) it produces the proper html I would expect. Why is ASP.NET messing with my link tag for my Css but not the script tag for the javascript?
Is there something special about the link tag to make ASP.NET think it needs to mangle it?
回答1:
This is a separate answer based on approach and might be more what you are looking for. The reason I found for the string mangling is the HtmlLink object has internal handling of the href value during rendering. Using .NET Reflector I found an Overrides RenderAttributes method. This is the code for it:
Protected Overrides Sub RenderAttributes(ByVal writer as HtmlTextWriter)
If Not String.IsNullOrEmpty(Me.Href) Then
MyBase.Attributes.Item("href") = MyBase.ResolveClientUrl(Me.Href)
End If
MyBase.RenderAttributes(writer)
End Sub
What I believe is happening is the RenderAttributes method is being called before your helper line is being parsed and is using ResolveClientUrl against the string "<%= MyNamespace.Helpers.UrlHelper.CssRoot %>Site.css". The solution of using "~/" URL strings isn't affected by this because ResolveClientUrl is able to understand that notation.
I see two solutions for you at this point. 1) Use the Edit #2 approach of injecting the helper's URL string into the element during Page_Load or Page_PreRender, or 2) Create your own Overrriden version of the HtmlLink element that doesn't try to use ResolveClientUrl. #1 would definitely be the easier solution.
Hope this helps shed some light on the issue.
回答2:
Perhaps a solution would be to specify your <link>
and <script>
tags from your master page's codebehind.
private void ConstructLinkAndScriptTags()
{
string cssTag = "<link href='" + MyNamespace.Helpers.UrlHelper.CssRoot + "Site.css' rel='stylesheet' type='text/css' runat='server' />";
cph.Controls.Add(new LiteralControl(cssTag));
}
回答3:
You could try changing
<link href="<%= MyNamespace.Helpers.UrlHelper.CssRoot %>Site.css" rel="stylesheet" type="text/css" />
to
<link href='<%= MyNamespace.Helpers.UrlHelper.CssRoot %>Site.css' rel="stylesheet" type="text/css" />
Note the single quotes on the second instance
回答4:
Try runat="server" tags in the elements
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<link runat="server" href="<%= MyNamespace.Helpers.UrlHelper.CssRoot %>Site.css" rel="stylesheet" type="text/css" />
<script runat="server" src="<%= MyNamespace.Helpers.UrlHelper.JavascriptRoot %>jquery-1.3.2.min.js" type="text/javascript"></script>
<asp:ContentPlaceHolder ID="cphHead" runat="server">
</asp:ContentPlaceHolder>
</head>
Edit: Do you have to use the helper object? Is it doing more than just making your links dynamic? When runat="server" is set, you can sometimes use dynamic URLs using the ~ character. You could try this instead:
<head runat="server">
<link id="SiteCssLink" runat="server" href="~/Css/Site.css" rel="Stylesheet" type="text/css" media="all" />
</head>
Edit #2: Try injecting the URL into the link element from the Page_Load or Page_PreRender events in the code behind of the page. You will need the element to have runat="server" for this to work.
Protected Sub Page_PreRender(ByVal sender as Object, ByVal e as System.EventArgs) Handles Me.PreRender
SiteCssLink.Href = Page.ResolveClientUrl(String.Concat(MyNamespace.Helpers.UrlHelper.CssRoot, "Site.css"))
End Sub
回答5:
It was not wise for ASP.NET team to make link tags auto-adjust their href attributes, but the best way I've found to deal with it is to:
- Dynamically insert the link tag into a Literal control.
- Remove the runat="server" from the head tag.
回答6:
It may be a bit hacky, but gets the problem solved, and looks "somewhat" like regular html.
<link <% this.Response.Write( "href=\"" + Links.Content.Site_css + "\""); %> rel="stylesheet" type="text/css" />
Note that in this example I am u sing T4MVC. As posted by Chris Porter, the problem is href. By calling the Response.Write you get around that. Enjoy!