I am using the MVC to add a title to the masterpage with a content place holder. The default MVC masterpage template uses the following code:
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server"/></title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
</head>
When I try to add defaulted text to the front of the content holder, it doesn't show the text in the final rendered page. I am trying to get the page to show a default title with appended contentplaceholder text.
Example:
(Default Text) (ContentPlaceHolder Text)
My Page - About Us
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>My Page - <asp:ContentPlaceHolder ID="TitleContent" runat="server"/></title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
</head>
I am looking for a way to accomplish this without having to use code behind. Any ideas?
It seems we should use
<asp:Literal runat="server" Text=" - MySite" />
instead of
<asp:LiteralControl runat="server" Text=" - MySite" />
mentioned in the article, because otherwise we get "Unknown server tag" error.
After looking further, Phil Haack actually posted an article which was a solution to my question. It can be found at Haacked.
In summary he said that everything that is rendered in the head is rendered as a control, and the fix for my question above is to put an asp literal control in the title to have it correctly generate the text.
<%# Master ... %>
<html>
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="titleContent" runat="server" />
<asp:LiteralControl runat="server" Text=" - MySite" />
</title>
</head>
...
Why?
<title>
<asp:ContentPlaceHolder ID="titleContent" runat="server" />
<%= "- My Site" %>
</title>
Works just as well. Without the hassle?
I prefer to use this:
<title>Site Name - <%=Page.Title%></title>
Much cleaner than using a literal control..
If you are using MVC and are passing the title in some object from the controller to the page I would use inline code to display this.
We use the MVC contrib functions to get typed data directly from the view data in the master page thus:
<head>
<title>My Page - <%= ViewData.Get<Model.Page>().Title %></title>
</head>
As a point of note we have removed all code behind files from every view we have to make the views more legible, we find this much better than having code behind for each view.
Related
I'm new to Asp.net and bootstrap. I referenced bootstrap.min.css in my html and I have gridview control I want to style with "table table-striped" class. Visual studio intelisens seems to fail to recognize table-striped class and it's not working when the program runs. Any ideas what I'm doing wrong?
Here's my html source:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="NotDelivered.aspx.cs" Inherits="PapaBobs.NotDelivered" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="Content/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<form id="form1" runat="server" class ="container">
<div class ="form-group">
<asp:GridView ID="notDeliveredGrid" runat="server" CssClass ="table table-hover table-striped"></asp:GridView>
</div>
</form>
<script src="Scripts/bootstrap.min.js"></script>
<script src="Scripts/jquery-3.3.1.min.js"></script>
</body>
</html>
Your current href value specifies relative path to css file and browser just cannot load it because this path doesn't exist. Update link to the following
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
Also consider using bundling.
I'm looking for validation here.
Some initial definitions I use:
"gator tags" are the <% %> tags for executing 'at render' code
Given the following:
<%# Page Language="C#" %>
<html>
<head runat="server">
<!-- meta description --><meta runat="server" id="meta_description" name="description" content="" visible="false" />
<link rel="canonical" href="<%=Context.Request.Url.AbsoluteUri %>" />
</head>
<body>
<h1>ASPNet Head runat=server parser bug.</h1>
<p>Inspect the source and look for <link rel="canonical" and see that you have the Render code enclosed with <% %> being sent to the browser.</p>
</body>
</html>
First, take notice of the render code in the <link rel="canonical" href="<%= Context.Request.AbsoluteUri %>" />. This is intended to output the AbsoluteUri for the current page (please refrain from the distraction about link rel=canonical semantics... I acknowledge this may not be the ideal way to do this)
When you run this code, the HTML sent to the browser is as follows:
<html>
<head>
<!-- meta description --><link rel="canonical" href="<%=Context.Request.Url.AbsoluteUri %>" /><title>
</title></head>
<body>
<h1>ASPNet Head runat=server parser bug.</h1>
<p>Inspect the source and look for <link rel="canonical" and see that you have the Render code enclosed with <% %> being sent to the browser.</p>
</body>
</html>
Notice how the render code within <% %> is output into the HTML stream, and not executed?
The major bug I see is that the ASP.Net parser doesn't adequately kick into Code Parsing state for the link tag, but instead grabs the whole string "<%= Context.Request.Url.AbsoluteUri %>" and shoves that into the (string)Href property for HtmlLink. (You can verify this by adding <%asdf%> somewhere on the page to see the ASP.Net parser's generated source and search for 'AbsoluteUri').
The odd thing is that Head runat=Server seems to kick the ASP.Net parser into a state where every tag, with or without 'runat=server', gets built as a server control. This has several side effects that I've noticed over the years, like whitespace slamming and others.
When you remove runat="server" from the HEAD tag, it works properly. The expected behavior is the Context.Request.Url.AbsoluteUri is properly emitted as: http://localhost:5678/HeadParserBug.aspx
I don't want this to be a discussion, but a validation by stackoverflow community of the problem. Can the ASP.Net community at large validate this find? Thanks.
I'm writing a ASP.NET Web Application and I'm running into trouble getting the CSS styles to be applied. Currently I have a Master Page and one Content Page. My Master page is getting the CSS style applied to it, but the Content page is not. The funny thing is in design view the style is being applied to the Content page but once it is ran the browser doesn't apply it. I've tried internal and external style sheets. Inline does work but I'd like to avoid inline. Here is some sample code of what I have and tried
Master Page:
<head runat="server">
<title></title>
<link rel="stylesheet" type="text/css" href="~/Styles/MasterStyleSheet.css" />
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
Content Page:
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<link rel="stylesheet" type="text/css" href="~/Styles/LoginStyleSheet.css" />
<!-- <link href='<%= ResolveUrl("~/Styles/LoginStyleSheet.css") %>' rel="stylesheet" type="text/css" /> I tried this as well-->
</asp:Content>
I've added the simple css file just so people could see that the syntax is correct:
LoginStyleSheet.css
#usrLabel {
color:Blue;
background-color:Aqua;
}
#Label4 {
background-color:Black;
}
Any help would be greatly appreciated
Update #1
HTML output for header:
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="../Styles/MasterStyleSheet.css" />
<!-- <link href="<%= ResolveUrl("~/Styles/MasterStyleSheet.css") %>" rel="stylesheet" type="text/css" /> -->
<!-- <link rel="stylesheet" type="text/css" href="../Styles/LoginStyleSheet.css" /> -->
<!-- <link href='/Styles/LoginStyleSheet.css' rel="stylesheet" type="text/css" /> -->
<!-- <link rel="stylesheet" type="text/css" href="~/Styles/LoginStyleSheet.css" /> -->
<!-- <link rel="stylesheet" type="text/css" href="../Styles/LoginStyleSheet.css" /> -->
<!-- <link rel="stylesheet" type="text/css" href="/Styles/LoginStyleSheet.css" /> -->
</head>
A lot of <link> elements are currently commented out but those are all different ways I've tried.
Update #2
First I appreciate the many responses. They have all been geared towards figuring out why my external css file won't work. However, if i try internal css style sheet it still doesn't work. Only inline css works. Perhaps if we could figure out what was wrong with why internal css styling wont work that would solve the same issue with external css style sheets
As you have already realised, the following won't translate into an absolute path, because it is not an asp.net object...
<link rel="stylesheet" type="text/css" href="~/Styles/LoginStyleSheet.css" />
Instead, try using this...
<link rel="stylesheet" type="text/css" href="<%=VirtualPathUtility.ToAbsolute("~/Styles/LoginStyleSheet.css")%>" />
UPDATE (after updated question)...
If the HTML sent the browser is as follows, then I believe LoginStyleSheet.css is either in a different location, or has some file permissions that are stopping it being served correctly...
(I have removed commented out lines, and added the line starting with **... the ** should NOT be included)
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="../Styles/MasterStyleSheet.css" />
**<link rel="stylesheet" type="text/css" href="../Styles/LoginStyleSheet.css" />
</head>
ALSO #aRsen49 highlights a possibility in his answer... and that is that the CSS file is loading correctly, but the CSS is incorrect. Have you double checked that the CSS matches as it should (remembering that # denotes an id where as . denotes a class)?
FURTHER UPDATE
If #Trisped is correct in his assumption, I think I might have an idea what is going wrong...
If usrLabel and Label4 are asp objects (such as <asp:Label>), the fact you're using Masterpages means that the actual id of the controls in the HTML sent to the browser will not be usrLabel and Label4, but in fact they'll be something like ct100_Content1_usrLabel and ct100_Content1_Label4... so your CSS as you currently have it will not link up correctly.
So I would recommend you either update your CSS to use the id's sent to the browser, or (and this would be my preference) you should add CssClss="usrLabel" attributes to each of the objects, and then update your CSS to .usrLabel instead.
Ok so here was the fix. So in my html the id was label4. However, because it was in a content page with a contentplaceholder id of ContentPlaceHolder1 once the html was actually generated the label's id was being changed from label4 to ContentPlaceHolder1_Label4. Therefore i had to change my css code. BTW f12 on ie works wonders. Thanks again for all the help. Sorry it was something as simple as an id being wrong.
In your master page, define a HEAD element and then mention the link for CSS classes. Then it would work on all your content pages. I have found a good reference for you here
If you use Visual Studios "drag and drop" the CSS sheet in your code.
If it still wont work, double check your CSS.
For example:
Did you create CSS Classes (CssClass = ) for ASPX Elements?
Are Class names right?
etc.
UPDATE
I know this might sound odd.. But Close down VS and restart it. Then Display the Page again. Furthermore.. When you display the page press F5! I believe your cache or similar might be the problem.
Try:
Open the page in Chrome
Right click on an element which is applying the style (something in the master page) and select "Inspect element".
In the window that pops up copy everything in the "Styles" panel (this panel is usually on the right side, just under computed style).
Right click on an element which is not applying the style and select "Inspect element".
Compare what is in the Styles with what you copied earlier.
If that does not get you on the right track then we will need one or both of the following:
The rendered html of a page which is not working. This should be the complete file. The page should not reference external resources like CSS or JS files.
A master page and content page which exhibit the issue.
Please note that these should be basic pages which exhibit the issue (not a production page with multiple controls on it).
I am stuck with this error and found a work around and the solutions works for me, but i i would like to know is it the best way to fix the issue and i want to make sure that it wont affect any other pages badly. Hope the experts will help.
If this was the best solution then many of you can save your heads.
This error occurs when a code block is placed in the MasterPage. Place the code block in a placeholder to resolve the issue.When adding AJAX extenders to your Web page, it will attempt to register scripts in the head. If code blocks are present in the MasterPage, an error might occur.
To resolve this issue, simply move the code block into a placeholder in the head of your MasterPage, like so:
<head id="Head1" runat="server">
<title>Untitled Page</title>
<link href="StyleSheet.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="myPlaceholder" runat="server">
<script language="javascript" type="text/javascript" src="<%= Page.ResolveClientURL("~/javascript/global.js")%>"></script>
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="head" runat="server"></asp:ContentPlaceHolder>
</head>
The error is logical you can not confuse the rendered controls after they rendered by using the <%= %>
One way to solve this issue is to use a literal control, and render the script line on code behind.
<asp:ContentPlaceHolder ID="myPlaceholder" runat="server">
<asp:Literal runat="server" ID="txtIncludeScript" EnableViewState="false"></asp:Literal>
</asp:ContentPlaceHolder>
and on code behind. Check for null because if you change the placeholder the literal is null. Also set EnableViewState=false because you set it on every Page_Load and you do not wish to save it to viewstate.
if(txtIncludeScript != null)
{
txtIncludeScript.Text =
string.Format("<script language=\"javascript\" type=\"text/javascript\" src=\"{0}\"></script>",
Page.ResolveClientUrl("~/javascript/global.js"));
}
ContentPlaceHolder requires a master page, so you can replace that tag with some other element that can be ran at the server in case your page does not have a master page and you cannot get rid of the
<head id="Head1" runat="server">
<title>Untitled Page</title>
<link href="StyleSheet.css" rel="stylesheet" type="text/css" />
<div runat="server">
<script language="javascript" type="text/javascript" src="<%= Page.ResolveClientURL("~/javascript/global.js")%>"></script>
</div>
<asp:ContentPlaceHolder ID="head" runat="server"></asp:ContentPlaceHolder>
</head>
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?
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.
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));
}
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
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
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.
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!