Hiding Literal control declaratively in header (ASP.NET web forms) - asp.net

I try to hide some Javascript code in header by just using declarations. The Visible property should be controlled by a setting in web.config (ConfigurationManager.AppSettings["key"]).
However, for some reason setting the Visible property like this has no effect - it is always true:
<head id="Head1" runat="server">
<asp:Literal ID="JSLiteral" runat="server" Mode="PassThrough" Visible='<%# false %>'>
Some JS
</asp:Literal>
</head>
It is probably linked to page life cycle in ASP.NET. It works when setting this property in Page_Load event, but that's not what I want as I need to insert this block to a lot of web applications, and I don't want to recompile all of them.
Any ideas how this could be accomplished with minimal effort in ASP.NET? I don't want to mess around with the JS code, which needs to be added in header - it is code of a third-party.
Thanks in advance and cheers,
Roger

Try the following.
protected void Page_Load(object sender, EventArgs e)
{
Head1.DataBind();
}
What you are using is a DataBinding expression. So DataBind() has to be called.

Related

ASPX EventValidation error with DropDownList

This must have an obvious solution, but I'm stumped. We are developing an application which is mostly XHR-based, so while we are using .aspx, very little is done with typical controls. However, in a few spots, we are just doing basic "throw this data into a spreadsheet for the user" things with a couple dropdowns for timespan for reports, etc.
The problem is when we use asp:DropDownList controls, it immediately causes any page we put them in to throw Event Validation errors on submit. I have created test pages that do not share the rest of the application's master pages (aka, no JS at all modifying things client side) just to be sure that we don't have some stray JS causing issues.
If I remove the DropDownList in the following example, the button click happens just fine. If I click the button with the page sitting as shown, it throws the Event Validation error.
However, other applications running on the same machine, in 4.0 Integrated app pools, do not exhibit this behavior, so I'm assuming it has something to do with the configuration. The web.config is pretty standard...tried turning httpCompression section off in a desperate attempt, but to no avail.
Does anyone have a suggestion on where to start here? Please remember... There is NO CLIENT SIDE MODIFICATION going on. This is straight from the server to the browser, then 'click' on the ASP-generated button.
Turning off Event Validation in the page directive does eliminate the error, but I'd rather not turn off validation if I can help it.
Environment:
Windows 7 Pro
IIS 7.5
.NET 4.0 Integrated app-pool
Error happens in IE9/Chrome/Firefox/Safari
Page:
<html>
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="ddlDays" runat="server">
<asp:ListItem Text="30 Days" Value="30"></asp:ListItem>
<asp:ListItem Text="60 Days" Value="60"></asp:ListItem>
<asp:ListItem Text="90 Days" Value="90"></asp:ListItem>
</asp:DropDownList>
<asp:Button ID="butExport" Text="Export" runat="server" />
</div>
</form>
</body>
</html>
Codebehind:
protected void Page_Load(object sender, EventArgs e) {
butExport.Click += new EventHandler(butExport_Click);
}
void butExport_Click(object sender, EventArgs e) {
Syslog("clicked");
}
Form Data (according to Chrome Inspector):
__VIEWSTATE:/wEPDwULLTIwOTUzNjUzOTVkZIiv1cdholWibyWL8h5HASwxedB47NUpctCv8OQc1CWM
__EVENTVALIDATION:/wEWAgL0voCyDQKDgcL6CAX34hdaRiHyNiY1xLIh5Pr6aj5q8h8gGG875vMq1SXF
ddlDays:30
butExport:Export
OK, I started going through my project looking for any possible configuration item that could be causing issues. Turns out a co-worker used a WebControlAdapter and applied it to all DropDownLists and during the Render, did not use RegisterForEventValidation.
I don't particularly like the adapter, but in the interest of moving on with life, I left it there and while rendering bound items, I'm calling Page.ClientScript.RegisterForEventValidation for each value. This has fixed every problematic DropDownList we have in the application.
Thanks for the suggestions, all.

Question about the "runat" attribute in ASP.NET?

I went through this thread but couldn't understand much. I am very new to ASP/HTML/Server-side programming.
I tried running this code on a .aspx file:
<form id="form1" action="Default.aspx">
<div>
<asp:Label ID="lblName"></asp:Label>
</div>
</form>
And I got an error when I tried to use this in the CodeFile:
protected void Page_Load(object sender, EventArgs e)
{
lblName.Text = "123";
}
"lblName does not exist".
But if I use runat="server" attribute with the label, then this code works.
Also, is there any concept of nesting the runat attribute. e.g, If I specify runat=server for the form above, will all my controls inside the form automatically be configured to run at server? How does this attribute work?
In which case would I be required to specify runat=server for the and for the tag? How does the server-side know that the label is inside the form if I don't have a form object at server side? Or am I missing something?
Any element marked with runat="server" lets the framework know that this will be a control on the server side. This article has more details:
Exploring the Runat Attribute
Nope, there is no such nesting available in ASP.NET, you have to specify "runat" to every control that you want to use in code behind and that is part of ASP.NET web library.
Because ASP.NET can only recognize difference between client side tag (the html that runs on browser) and server side tag with help of "runat"

How to avoid Initialization of web user control inside aspx?

I have an aspx page which contains a web user control as below.
<html>
<body>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server">
<uc1:WebUserControl Visible="false" ID="WebUserControl1" runat="server" />
</asp:PlaceHolder>
<asp:Label ID="Label1" runat="server" Text="This is visible"></asp:Label>
</div>
</form>
</body>
</html>
In the Page_Load method of the above page I am setting the Visible = true/false (based on some condition) for the WebUserControl1. WebUserControl1 contains lots of control itself. But I don't want to initialize the controls inside WebUserControl1. Is there anyway we can avoid initializing the ChildControls of WebUserControl1?
From you description, it sounds like the heavy lifting that is being done in the user control is done in the Init event of the user control. May I suggest moving the heavy lifting out of that event to, possibly, the Load event. Then, as #Brian pointed out, you should be able to check if the control is visible and start the heavy lifting if it is.
Code-Behind for your User Control:
protected void Page_Load(object sender, EventArgs e)
{
if (this.Visible)
{
//do heavy lifting here
}
}
If you don't put some kind of conditions on whether or not you lift, you will always lift.
Controls will be added to the control tree and that can't be avoided unless you add controls dynamically (which can be a pain), but you have to handle the backend logic checking. In your user control code, you need to check for Visible = true when you attempt to process server-side logic, and only process when true.

Add packaged javascript to page from ASP.NET server control?

Is it possible to create an ASP.NET server control that packages some javascript that will be emitted to the aspx page at design-time rather than run time? I am trying to create a control that will have "default" javascript. I can add jvascript using RegisterClientScriptBlock, but then a web developer can't modifiy the javascript - it is unavailable a design-time in this scenario. Is there a way to change the ToolBox properties so that when a web developer drops the control onto the page, the javascript is added in a separate script tag as well?
When I need to do this I make a property on the control that will inject the tags, and then the web dev makes a asp:literal tag that has visibility none and viewstate disabled, that has all the JS they need.
then in the page's code behind they inject the literal's text into the server controls properties.
<asp:Literal ID="Literal_HtmlHeader" runat="server" Visible="false" EnableViewState="false">
<script></script>
<style></style>
</asp:Literal>
there are probably better ways... but this is simple and effective for me.
protected void Page_Load(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(this.Literal_HtmlHeader.Text.Trim()))
{
//inject css and js into header.
Page.Header.Controls.Add(new LiteralControl(this.Literal_HtmlHeader.Text));
// or add to your control cause it knows how to add the tags so there is no duplication.
ServerControl c = new ServerControl();
c.HtmlHeaderCode = this.Literal_HtmlHeader.Text.Trim();
}
}

How do I make my ASP.NET server control take an embedded code block as a property value?

I have a custom server control with a property of Title. When using the control, I'd like to set the value of the title in the aspx page like so:
<cc1:customControl runat="server" Title='<%= PagePropertyValue%>' >
more content
</cc1:customControl>
When I do this, however, I am getting the exact String <%= PagePropertyValue%> being displayed rather than the Property Value that I would like to see.
So after trying the databinding expression (as suggested below). I don't get the string literal that looked bad but I don't get anything else either.
<cc1:customControl runat="server" Title='<%# PagePropertyValue%>' >
more content
</cc1:customControl>
What do I need to do to my custom control to take this sort of value? Or is there something I need to do to the page.
You cant. <%= %> will write the string directly to the response-stream, which happens after the server control is constructed. See this post for an explanation.
So its either codebehind, or <%# + databinding as Zachary suggests.
As a followup to my own question, I have discovered that what I really wanted was to use ASP.NET Expressions using the <%$ syntax, since what I wanted to do was put in localized content.
This can be done with apparently no extra handling on the server control side.
<cc1:customControl runat="server" Title='<%$ Resouces: ResourceFile, ContentKey %>' >
more content and controls
</cc1:customControl>
This works just fine.
Try using databinding syntax:
<%# PagePropertyValue %>
For the bind property value to work correctly as suggested, you will have this in the aspx or ascx file :
<cc1:customControl runat="server" Title='<%# PagePropertyValue %>' >
more content
</cc1:customControl>
You will then need to actually bind data in your page wich you have to add this in you code behind file (code in C#)
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}
That way it will bind the data in your ascx or aspx file.
Note that this is specific to control attributes. When using the <%= syntax outside control attributes meaning anywhere else in the page the syntax works as expected. So this
<%=GetCapitalUserName()%>
would call the correct method and inject the result of the call in the page.

Resources