ASPX Server side comments messing up controls collection - asp.net

I am having one of the weirdEST issue I have ever faced. Its ridiculous.
Server side comments gets added as a LiteralControl to the original container control. I know it sounds really crazy, but thats what I am experiencing here :(
My environment: Visual studio 2012, IIS 7, .net frameworks 4.0
I am copying my test page here:
Default.aspx page:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div runat="server" id="divTest">
<%--test--%>
<%--test--%>
</div>
</form>
</body>
</html>
Default.aspx.cs:
using System;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(string.Format("divTest Control count: {0}", divTest.Controls.Count));
}
}
web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
</configuration>
The resulting page shows the output:
divTest Control count: 3
The funniest part is that, I tried to run this same page in 3 other boxes,( with exactly same config/environment) and it worked as expected in 2 of them and the other one showed the same result as mine. Again, if I change the build target framework version to 2.0, it shows the expected results (divTest Control count: 1). This happens only when I build it in 4.0
Any idea what could be the reason for this odd behaviour? Am i missing something here?
Thanks
Benjamin

The extra LiteralControl is not from comment but white spaces that surrounds it.
Same thing happend to me when switched from VS.NET 2010 to 2013 (yes, just upgraded VS.NET - no change in website target framework - 4.0)
The solution in my case was to use FindControl() method instead of accessing ControlCollection directly by index.

Related

Error in ASP.net : BC30037: Character is not valid

I have started learning asp.net. I went through basics and now i am started to build small application.
I am using VS 2012 and created Empty Web Application Project with VB.
I can see web.config created automatically and following are the line written in it :
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
</configuration>
I created Default.aspx file and wrote following lines of code :
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" %>
<%
HelloWorldLabel.Text = "Hello, world!";
%>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label runat="server" id="HelloWorldLabel"></asp:Label>
</div>
</form>
</body>
</html>
When I am running this application on browsers, I am getting following error that page :
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: BC30037: Character is not valid.
Source Error:
Line 2:
Line 3: <%
Line 4: HelloWorldLabel.Text = "Hello, world!";
Line 5: %>
Line 6:
Source File: c:\users\anjum.banaras\documents\visual studio 2012\Projects\Students\Students\Default.aspx Line: 4
Can any one help me on this ? I am just beginner on asp.net. Your help can save lots of my time.
Thanking you in advance !!
You've set the programming language of the page to VB (Visual Basic), but the line it is complaining about is written in C# syntax. Either change the line to be valid VB code:
HelloWorldLabel.Text = "Hello, world!"
(I think that removing the ; is all that's needed, but I never code VB so I'm not sure)
or change the page language to C#:
<%# Page Language="c#" AutoEventWireup="false" CodeBehind="Default.aspx.vb" %>
I was getting this error since my designer file was missing from the solution (I don't know how,seriously). So try adding a designer file for the aspx file in the solution; it worked for me.
I copied my code to another editor (notepad++) and was able to see the problematic chars. After i removed them, the code worked again.
��myClass.myArray(28) = "myFirstValue"
��myClass.myArray(29) = "myValue"

ASP.NET C# and creating pages from master - "inherits" value is always wrong?

I'm relatively new to ASP.NET (haven't touched it since .NET was first introduced). I'm using Visual Studio Express For Web 2012.
I've created a master page to work with. However, whenever I create a new page, the default value for "inherits" at the top of the page causes the page to not load, with a "could not load type" error.
I haven't even started coding yet, so I'm not sure what it's looking for.
Edit to add:
Top of a new page looks like this:
<%# Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="login.aspx.cs" Inherits="Bitfork.login" %>
The generated code behind page:
namespace Bitfork
{
public partial class login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
This issue was caused in my website when I was using CodeBehind property in <%# Page ..> directive,
As soon as I changed it to :CodeFile , it worked without the need to recompile every time. I guess from ASP.NET 2.0 onwards this is the case for website templates.
What I observed was that [ framework 4 ], when I create website, the <%# Page ..> directive contains CodeFile. When create WebApplication, then the <%# Page ..> directive contains: CodeBehind.
This post may be helpful: ASP.Net 3.5/4.0 CodeBehind or CodeFile?
Issue resolved - I didn't realize I needed to recompile the page between each page load.

How to disable/override naming container's ID generation of Content page's control id's

We have an existing ASP.Net web application which we want to convert into using masterpages.
In the process of doing this, I found that the HTML id's generated for the HTML elements are prefixed with the ContentPlaceHolder's id. And this is what can be expected when we set the ContentPlaceHolder's clientidmode=static.
Now since we have a lot of existing client side scripts that make use of the id's, this part breaks when we use masterpages, and it is quite a big job to run through all our javascript to make sure we call the javascript using Control.ClientID, as a lot of it is hardcoded.
Is there a way to disable the prefixing? I can succeed doing this, if I create every control setting its ClientIdMode=static, but then again I would prefer settings this once, to ensure that all controls are have their ClientIdMode=static. Is that possible? Or is it possible to override the NamingContainer of the ContentPlaceHolder?
The platform is .Net 4.0
(After fixing the above problem with ClientIdMode=static in the web.config as described in the answer below), I have bumped into the problem that the "name" attribute is automatically generated, and is not set to whatever it was before I introduced masterpages. This gives me a problem with my existing server code, which has many Request.Form[]. Any idea what best practice is here to solve this problem?
Thanks
Jihad
You can have ClientIDMode at Page Level:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" ClientIDMode="Static" %>
MasterPage Level:
<%# Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" ClientIDMode="Static" %>
and Web.Config level (making all pages inherit this behavior):
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<pages clientIDMode="Static"></pages>
</system.web>
In case you don't target .Net framework 4, and the clientIDMode enum is not available, you can simply override the control class. Here is an example with HtmlGenericControl but can be done with any other control:
public class NoNamingContainerControl : HtmlGenericControl
{
public NoNamingContainerControl(string tag) : base(tag) { }
public override string ClientID
{
get
{
return this.ID;
}
}
}
This code should work on any .Net framework versions, although in .net 4 you should probably use the clientIDMode

Label doesnt exist in the current context

why m i getting this error "The name 'lblHelloWorld' does not exist in the current context"? How do i fix it?
<%# Page Language="C#" AutoEventWireup="True" Inherits="_Default" Codebehind="Default.aspx.cs" %>
<!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 id="Head1" runat="server">
<title>Hello, world!</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="MainScriptManager" runat="server" />
<asp:UpdatePanel ID="pnlHelloWorld" runat="server">
<ContentTemplate>
<asp:Label runat="server" ID="lblHelloWorld" Text="Click the button!" />
<br /><br />
<asp:Button runat="server" ID="btnHelloWorld" OnClick="btnHelloWorld_Click" Text="Update label!" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ajaxTesting
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnHelloWorld_Click(object sender, EventArgs e)
{
lblHelloWorld.Text = "Hello, world - this is a fresh message from ASP.NET AJAX! The time right now is: " + DateTime.Now.ToLongTimeString();
}
}
}
I tried cleaning and rebuliding; deleting the designer.cs file and recreating it but was of no use.
I think the problem in your designer.cs file.Try to add a reference manually for this label in the designer.cs file.
EDIT:
The problem after revision to your code is in the name space.
To fix your problem::
Replace your line by this:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ajaxTesting._Default" %>
The Best possible solution would be:
Copy all the lines of code between <body> and </body>
Create a new aspx page in your project.
Replace the <body> tag with the one you copied
Similarly copy and paste the code from .cs file also.
I feel this should solve your problem.
Step 1:
Copy off the aspx form, codebehind and designer files and re-create the form again by copying and pasting.
Step 2:
If step 1 doesn't fix it: In visual Studio, go to Edit -> Find and Replace -> Find in Files and search within your project for a control with the same name.
Step 3
Close out Visual Studio and all browsers. Temporarily stop IIS and navigate to the temp ASP.NET files folder (the path may be different on your machine):
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files
Start deleting everything from the site folder in here, starting at the bottom (because you may get ACL folder permission restrictions).
Re-start IIS and try again (after you have tried one or both of previous steps).
Another possibility that I had:
If you duplicate the .cs file, for example: duplicate "Default.aspx.cs", getting "Default.aspx - Copy.cs" (now you have the two files on the same folder),
the result will be: the file will appear in the project file list. Even excluding the copied file out of the project, but leave the file on the same folder will not solve the problem.
In order to avoid this issue, remove the copied file out of the project folders.
I had this problem after importing source files from someone else. After a while I discovered I didn't have any designer.cs file.
I followed this solution. Especially the part about "Convert to Web Application". That did the trick for me!
I faced this same problem in asp.net website (3.5) In my case there were 2 copies of the same file.
Compute.aspx
Compute_backup.aspx
I excluded the #2 file from the website and it worked for me.
I completely removed the apex file a re-created it and left to object name _Default. I then set about adjusting the C# code accordingly and voila, it worked OK. This was when working with ASP.NET 3.5 in VS2008. In this case I got it to work, but there is still something funky about VS2008 or this would not be necessary.

ResolveClientUrl works differently in ASP.Net 4 and 3.5

[Apologies if my question title does not accurately describe my problem- if you can think of a better title and have the permissions to change this then please feel free to change it!].
I think that I have stumbled upon a minor breaking change between ASP.Net 3.5 and 4.0.
[Edit: I have confirmed that there is a change in behaviour twix 3.5 and 4.0 - see my answer]
Here is the scenario: -
I have a ASP.Net 3.5 web application.
I have a trivial user control {appRoot}/Controls/Widgets/MyPictureAndTextWidget.ascx that essentially contains some text and another user control ({appRoot}/Controls/Widgets/MyPicture.ascx).
For the most part, this control is used in the normal fashion - i.e. including it in the mark up of other pages but I have one instance where I need to obtain the HTML to render on the client using Ajax.
The way I achieved this was to write an asmx web service that programmatically created a new Page and dynamically `LoadControl' the user controls and then captured the output from the rendering of the page in a string builder - particulary inelegant but it worked! See bottom for the source.
However, after upgrading the project to Asp.Net 4.0, the above code no longer works as it used to; the image, when rendered has src="../images/xxx.png (note the '../' which is not wanted).
I have created a little demo app http://cid-916198839f3e806c.office.live.com/self.aspx/Public/TestingImageWTF.zip if you want to run it for yourselves. When you compile the app using 3.5, it works (i.e. you see 2 pictures of a spider on the test page) but when you compile and run under 4.0, you only see 1 spider (the other image has the wrong URL).
The only explanation that I can come up with is that the ResolveClientUrl method (which the Image control will use in order to work out what is the relative path to the image from the currently executing page) is behaving differently. The fact that the image url is coming out as "../images/xxx.png" means that the Image control 'thinks' it is executing in a page that has a path like '{appRoot}/folder/handler' when running under 4.0 but it thinks it is running in a context '{appRoot}/handler' under 3.5.
I hope this is making sense to you - sorry if I am not describing the problem very clearly or concisely.
Can anyone either tell us how: -
to restore the 3.5 behaviour (without reverting to the 3.5 framework obviously!)
or a better way of generating the HTML in the web service in the first place?
The source
A full test application can be downloaded from here http://cid-916198839f3e806c.office.live.com/self.aspx/Public/TestingImageWTF.zip
Web Service
[WebMethod]
[ScriptMethod]
public string GetWidgetHtml(int number)
{
var pageHolder = new Page
{
//AppRelativeVirtualPath = "~/" // I tried playing with this but it made no difference!
};
for (int i = 0; i < number; i++)
{
var viewControl = (MyPictureAndTextWidget) pageHolder.LoadControl(#"~/Controls/Widgets/MyPictureAndTextWidget.ascx");
pageHolder.Controls.Add(viewControl);
}
var output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
StringBuilder sb = output.GetStringBuilder();
string fulloutput = sb.ToString();
return fulloutput;
}
Here are the contents of my user controls
Controls/Widgets/MyPictureAndTextWidget.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="MyPictureAndTextWidget.ascx.cs" Inherits="TestingImageWTF.Controls.Widgets.MyPictureAndTextWidget" %>
<%# Register TagName="Picture" TagPrefix="widget" Src="~/Controls/Widgets/MyPictureWidget.ascx" %>
<div style="background:#EEEEEE; border:1px dashed;">
<h4>My control</h4>
Some text from the widget ....:
<br /><widget:Picture runat="server" />
</div>
Controls/Widgets/MyPictureWidget.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="MyPictureWidget.ascx.cs" Inherits="TestingImageWTF.Controls.Widgets.MyWidget" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
image.ImageUrl = "~/images/spider.png";
}
</script>
<asp:Image ID="image" runat="server" />
oSo here is at least part if the answer.
Question: Does ResolveClientUrl working differently in ASP.Net 4 and 3.5?
Answer: Yes.
And the change in behaviour (that I know of) is that it treats PathInfo differently.
To demonstrate, make the following page.
<%# Page Language="C#" AutoEventWireup="true" %>
<!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">
<body>
<form id="form1" runat="server">
DateTime.Now.Ticks: <%= DateTime.Now.Ticks %>
<br />
<asp:HyperLink runat="server" NavigateUrl="~/PathInfoLinkTest.aspx">This links to ~/PathInfoLinkTest.aspx</asp:HyperLink>
<br />
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/PathInfoLinkTest.aspx/foo/bar">This links to ~/PathInfoLinkTest.aspx/foo/bar</asp:HyperLink>
<br />
ResolveClientUrl("~/PathInfoLinkTest.aspx/foo/bar") = <%= ResolveClientUrl("~/PathInfoLinkTest.aspx/foo/bar") %>
</form>
</body>
</html>
And run under .Net4 and .Net 3.5.
You will see that under 3.5:
ResolveClientUrl("~/PathInfoLinkTest.aspx/foo/bar") = 'PathInfoLinkTest.aspx/foo/bar'
whereas under 4.0 you get
ResolveClientUrl("~/PathInfoLinkTest.aspx/foo/bar") = 'bar'
The change seems to be a bug fix in response to the problems that these folk were having.
http://channel9.msdn.com/Forums/TechOff/256519-Am-I-crazy-here-but-there-appears-to-be-an-oversight-in-ASPNET
http://forums.asp.net/t/1138135.aspx/1
In essence, the bug in 3.5 is that if you are currently browsing the url http://host/app/page.aspx/foo/bar and you want to link to http://host/app/page2.aspx, then the URL as rendered on the client should be ../../page2.aspx.
Asp.Net 4 gets this correct!Asp.Net 3.5 doesn't - it outputs the link's url as 'page2.aspx' (so when clicked, the browser will request the page 'http://host/app/page.aspx/foo/bar/page2.aspx'. You can see a manifestation of this bug if you run the above page in .Net 3.5 and click on the 2nd hyperlink several times - then have a look in your browser's address bar!
Unfortunately the bug fix broke my code - because my code was relying on the (incorrect) behaviour of .Net 3.5: The web service request always has Pathinfo (the web service method name) and so when the controls render themselves, calls to ResolveClientUrl("~/xxx") (correctly) puts returns "../xxx".
I'm not sure about updates to the ResolveClientUrl method, but I do know that they made updates to how controls are rendered between .NET 4.0 and 3.5. You may want to try updating your web.config to include:
<pages controlRenderingCompatibilityVersion="3.5" />
Check out: http://www.asp.net/learn/whitepapers/aspnet4/breaking-changes#0.1__Toc256770141
Also, you might try using RenderControl as follows in your web service:
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(tw);
control.RenderControl(hw);
return sb.ToString();
Rick Strahl has an article that might be useful: http://www.west-wind.com/weblog/posts/2004/Jun/08/Capturing-Output-from-ASPNet-Pages (may be somewhat dated however...)
Hope this helps!
Try to remove the leading tilde symbol from the ImageUrl value.

Resources