Tuesday, November 4, 2008

Warnings with CSS classes and Masterpages in Visual Studio 2008

When you create a new masterpage in Visual studio 2008 that contains a link to a stylesheet it can happen that the IDE thinks that the classes defined in the stylesheet cannot be found even though the compiled website will use the classes defined in the stylesheet.

use the following code to replicate the issue.

{/MasterPage.master}


<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="testpages_master_with_css_problem_MasterPage" %>

<!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>Untitled Page</title>
<asp:Literal ID="Literal1" Visible="false" runat="server">
<link href="~/Styles/StyleSheet.css" rel="stylesheet" type="text/css" />
</asp:Literal>
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div id="someId1" class="someClass1">
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>



{/default.aspx}

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="testpages_master_with_css_problem_Default" Title="Untitled Page" %>

<asp:content id="Content2" contentplaceholderid="ContentPlaceHolder1" runat="Server">
<div id="someId2" class="someClass2">
<asp:label id="myLabel" cssclass="someClass3" runat="Server">This is text with styles from all classes and id's</asp:Label>
</div>
</asp:Content>



{/Styles/StyleSheet.css}

body
{
font-family: Arial;
font-size: medium;
font-weight: normal;
font-style: normal;
font-variant: normal;
text-transform: none;
color: #000000;
}
.someClass1
{
font-family:Times New Roman;
}
.someClass2
{
font-size:xx-large;
}
.someClass3
{
color:Red;
}
#someId1
{
font-style:italic;
}
#someId2
{
text-transform:capitalize;
}



If you open these pages in you Visual Studio 2008 IDE and wait a while in a page you will get warnings:



  • Warning 1 The class or CssClass value is not defined. C:\...\MasterPage.master 14 30 C:\...\Stylesheet classes problemsdemo\

  • Warning 2 The class or CssClass value is not defined. C:\...\Default.aspx 7 26 C:\...\Stylesheet classes problemsdemo\

  • Warning 3 The class or CssClass value is not defined. C:\...\Default.aspx 8 39 C:\...\Stylesheet classes problemsdemo\


However, if you open the page in a browser, all styles will be applied.



It seems that for ID's no warning for non-existant identifiers is given (I also checked using non existant ID's), but for classes the warning is generated.



There is some more odd behaviour at hand here. At the moment I give "someId2" a non-existant identifier ("someId2fdsaf") the warning for "someClass3" disappears.



The warnings also seem to depend on the CcontentPlaceHolder in the header, as soon as I remove that placeholder from "Default.aspx" all warnings in that file disappear...



However in the "MasterPage.master" this behaviour can not allways be reproduced. (I have seen this for the masterpage in my original project, but in this demoproject it doesn't solve the warning.)



If you remove the '~' from the link to the stylesheet then the warnings disappear but then you'd have a problem deploying your site to a place below the root of the site. This would however seem to indicate that the IDE has a problem solving this relative link.



This is not something critical, but when you use cssClasses a lot in your code you'd probably want to be warned if you made a mistake. (so unchecking CSS warnings on the project is not a solution to this problem)



I'm still researching this problem and will come back if I find a solution.



If anybody can provide help, it would be very welcome.



What I found on the Internet is that for '~' to work it needs to be run with runat="server". Lancerfisher wrote a nice piece about it. When I added his solution I was able to reproduce what I said above, that removing the ContentHolder from the head resolves the warnings.


If you edit your masterpage to resemble the following the warnings are gone


<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="testpages_master_with_css_problem_MasterPage" %>

<!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>Untitled Page</title>
<asp:Literal ID="Literal1" Visible="false" runat="server">
<link href="~/Styles/StyleSheet.css" rel="stylesheet" type="text/css" />
</asp:Literal>
</head>
<body>
<form id="form1" runat="server">
<div id="someId1" class="someClass1">
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>


but again this is not the solution.



Ok, problem is solved...

It seems that Microsoft figured that this was a bug too. :o) I installed Visual Studio 2008 SP1 and the problem was solved. Even the Literal was no longer needed. The original code above works Ok now.


I recommend however that you first test the servicepack in a non production environment however. This is a best practice for installing any service pack. Sometimes a service pack breaks more (by being more restrictive for security, for example), than it solves in your specific situation.

1 comment:

Unknown said...

Good article...I have installed VS2008 SP1 and the problem stills...