Dynamic styles aren't being applied - c#

I have a menu that I've built styles for and have some menu options that should not be shown to non-admin users. I've put a link to an asp.net page as a dynamic style. Here is the code:
<head runat="server">
<title></title>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Styles/DynamicStyle.aspx" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
the source of DynamicStyle.aspx:
protected void Page_Load(object sender, EventArgs e)
{
if(!Roles.IsUserInRole("Administrators"))
{
StringBuilder oSb = new StringBuilder();
oSb.AppendLine(".restricted");
oSb.AppendLine("{");
oSb.AppendLine("display: none;");
oSb.AppendLine("}");
Response.Write(oSb.ToString());
Response.End();
}
}
I have verified that it does emit the proper CSS.
here is a snip of the code that should be hiding the button:
<li>Events</li>
<li>Industries</li>
<li class="restricted">Institutions</li>
<li>Job Groups</li>
<li>Job Titles</li>
In Mozilla's inspector, it does not list the restricted as having been applied.
I have never tried to do this this way but have seen it done and am wondering what I am missing? Any help is appreciated.

You aren't returning the correct content type for CSS (it's returning type of text/html instead of text/css). Your code would work if you add Response.ContentType = "text/css";:
Response.ContentType = "text/css";
Response.Write(oSb.ToString());
Response.End();
But the real problem is you are simply "hiding" links that people shouldn't see... but if they view the page source, they can still see them. A better option is to not send those links to the client at all. One option is:
<li id="_admin1" runat="server">Institutions</li>
and then in your code behind:
_admin1.Visible = Roles.IsUserInRole("Administrators");
Now the html for that <li> won't even be sent to the client unless they are in the correct role.

Related

Adding CSS at runtime to an ASP.net master page.

I have an ASP.net web application, and would like to know if is it possible to change the CSS of a site at run time of a master page, and get the CSS file name from a SQL database and add it into the system ?
You can put on the top of the masterpage on aspnet literal and construct the link in the pageload of the masterpage that way you could put a css there
<asp:Literal ID="Css" runat="Server" />
Then on the page load
var cssfilename = GetCssFromDatabase();
Literal.Text = "<link rel=\"stylesheet\" media=\"all\" " + cssfilename + "\" />";
Yes it is. Use <head runat="server"> and you can put anything in there, simplest way probably a Literal control where you append the string from codebehind
Masterpage.master:
<head runat="server">
<title>Your Site</title>
<asp:Literal runat="server" ID="cssLiteral" />
</head>
Masterpage.master.cs:
cssLiteral.Text = "<link rel='stylesheet' type='text/css' href='"+strCssFileName+"' />";
You haven't provided much information of your case, yes it's possible in many ways. Here is a simple example how to change css-file in master-page from a content page:
First add a static variable for example in Global.asax (code in VB.Net)
Public Shared DefaultCssFile As String = "~/MyStyles.css"
In master pages header:
<asp:PlaceHolder runat="server">
<link rel="Stylesheet" type="text/css" href="<%= Page.ResolveUrl(MyApp.Global_asax.DefaultCssFile) %>" />
</asp:PlaceHolder>
Then just change the variables value as you see fit.
MyApp.Global_asax.DefaultCssFile = "~/MyOtherStyles.css"
There are several ways you can achieve this.
Best way I suggest you to use theme and skin file concept.
protected void Page_PreInit(object sender, EventArgs e)
{
switch (Request.QueryString["theme"])
{
case "Blue":
Page.Theme = "BlueTheme";
break;
case "Pink":
Page.Theme = "PinkTheme";
break;
}
}
here you can change the values of your theme run-time from code behind accurately. you can put your .css files into different themes. and as per database conditions you can change values of theme files.
hope this will help.

CSS Style Not Being Applied

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).

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)

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>

convert asp.net code to WebPart code issue

I am using SharePoint Server 2007 Enterprise with Windows Server 2008 Enterprise. I am developing using VSTS 2008 + C# + .Net 3.5 + ASP.Net. I have the following code which works correctly in ASP.Net (aspx) and I want to implement the same function in a WebPart and deploy into a page of SharePoint publishing portal site.
Any ideas how to implement? My major confusion is how to deal with the code in the head part of the following code? Any reference code or document?
Here is the aspx code I am using,
<!doctype html>
<html lang="en">
<head>
<title>Test</title>
<link type="text/css" href="tabcontrol/themes/base/ui.all.css" rel="stylesheet" />
<script type="text/javascript" src="tabcontrol/jquery-1.3.2.js"></script>
<script type="text/javascript">
$(function() {
$("#tabs").tabs();
});
</script>
</head>
<body>
<div class="demo">
<div id="tabs">
<ul>
<li>tab1</li>
<li>tab2</li>
</ul>
<div id="tabs-1">
<p>tab1 info</p>
</div>
<div id="tabs-2">
<p>tab2 info</p>
</div>
</div>
</div>
</body>
</html>
thanks in advance,
George
Check this links...
http://dotnet.org.za/zlatan/archive/2007/10/12/developing-ajax-web-parts-in-sharepoint-2007.aspx
http://www.bewise.fr/article/ptc/57/WSS-V3-Use-ASP-NET-AJAX-Framework-with-WSS-30.aspx
If you need help tell me that I can provide you a WebPart sample.
To include css or js files you can do something like this...
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
ClientScriptManager cs = Page.ClientScript;
string includeTemplate = "<link rel='stylesheet' text='text/css' href='{0}' />";
string includeLocation = Page.ClientScript.GetWebResourceUrl(this.GetType(), "App_Themes.MyButtons.css");
LiteralControl include = new LiteralControl(String.Format(includeTemplate, includeLocation));
Page.Header.Controls.Add(include);
includeTemplate = "<link rel='stylesheet' text='text/css' href='{0}' />";
includeLocation = Page.ClientScript.GetWebResourceUrl(this.GetType(), "App_Themes.MyMainModalDialog.css");
include = new LiteralControl(String.Format(includeTemplate, includeLocation));
Page.Header.Controls.Add(include);
}
In this sample I include MyMainModalDialog.css and MyButtons.css dynamically
For the CSS, you can use CssLink and CssRegistration:
// Custom CSS (fix the URL as necessary)
Microsoft.SharePoint.WebControls.CssLink cssLink =
new Microsoft.SharePoint.WebControls.CssLink();
cssLink.DefaultUrl = "/tabcontrol/themes/base/ui.all.css";
this.Page.Header.Controls.Add(cssLink);
I forget if there are other ways to handle custom javascript besides ClientScriptManager or Page.Header.Controls.Add(). There is a CustomJSUrl class but it doesn't seem to operate in the same way that the CssLink works.
Also, I believe your formatting script $(function() { $("#tabs").tabs() }) should be hooked to the page.load event rather than in the <head> block.

ASP.NET Webform css link getting mangled

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!

Categories

Resources