Conversion from Classic ASP to ASP.NET - asp-classic

I have to convert some code from classic ASP to ASP.NET
1) How can I best handle syntax as below, where it seems to fail because the code is inside a tag, and also perhaps because the condition is split over several tags.
2) Any tools or guidelines that are good on this kind of code?
3) Classic ADO.
<li><a<% if "" = myFolder then %> class="selected"<% end if %> href="http://<%= SERVER_NAME %>/"><%= getLocale("Home") %></a></li>
<% SQL = "SP_TOPNAV '" & lang & "'"
Set maNav = conn.execute(SQL)
do while not maNav.EOF %>
<li><a<% if maNav(0) = myFolder then %> class="selected"<% end if %> href="http://<%= SERVER_NAME %>/<%= maNav(0) %>"><%= maNav(1) %></a></li>
<% maNav.MoveNext
loop
Set maNav = Nothing %>
</ul>

ASP.net handles code split between several <%%> tags just fine. The problem lies elsewhere. Please edit your question to include the error message.

If your using .net 2.0 look into a asp:repeater that can bind to a datasource, if your using .net 3.5 look into a asp:listview. Those controls give you the ability to iterate through data and generate markup which is essentially what your doing.

You can always use ASP.NET's data controls such as Repeater, GridView, DataList to display collections of item. And you can customize their looks by modifying the ItemTemplate. You can also include the rendering conditional inside ItemTemplate too.
For example:
<asp:Repeater id="Repeater1" runat="server">
<HeaderTemplate>
<table border="1">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td> <%# Container.DataItem %> </td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Taken from: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.itemtemplate.aspx
You can always insert conditional logic inside <%# ... %> text. Or if the logic are complicated, you can code them inside the code behind file and call them from here.
Search for "ASP.NET If inside ItemTemplate" or "ASP.NET Condition in ItemTemplate" for more info.

Related

Prevent Visual Studio from adding child controls

I have a bit of a strange issue here. I created a custom control as such:
public class Textbox : System.Web.WebControls.Placeholder
{
if( [certain criteria are met])
this.Controls.Add(new System.Web.WebControls.Textbox());
}
When working in Visual Studio's designer mode, anytime I add one of my textboxes to the page:
<myControls:Textbox id="txtTest" runat="server" />
Visual studio has a habit of changing my markup to the following:
<myControls:Textbox id="txtTest" runat="server" >
<asp:Textbox runat="server" />
</myControls:Textbox>
This changes the final output markup so that two textboxes appear. Is there a way to prevent visual studio from doing this?
EDIT:
As per request, here is the page markup
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="TestApp.Test" %>
<%# Register Assembly="MyControls.WebControls" Namespace="MyControls.WebControls" TagPrefix="myControls" %>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<table>
<tr>
<td>
<asp:Label ID="lblTest" runat="server">Test Label:</asp:Label>
<myControls:TextBox ID="txtTest" runat="server" Width="80px"></myControls:TextBox>
</td>
</tr>
</table>
</asp:Content>
I think that's happening because your class inherits from the PlaceHolder control, which implements the TemplateControl class. I don't know if there was a reason for this, but it seems like it would be more approriate if you inherited from the TextBox control instead.
EDIT
Since you're using logic to render one of several controls, I would inherit from the WebControl class instead. This will allow you render basically anything you want. Although I must admit, what you're trying to do is probably going to require a substantial amount of work.
If I understand the issue correctly, you are having problems at design time and not runtime.
If this is the case, you should wrap your control add code with a test that ensures it is only executed when you are not in design mode. For example:
if ((!this.InDesignMode) && ( [certain criteria are met]))
this.Controls.Add(new System.Web.WebControls.Textbox());

ASP.NET Controls are not coming in Code-behind IntelliSense

I am having an aspx page where I have added one asp.net text box control with ID and RUNAT attribute. But in Code-behind I am not seeing this control's name in the intellisense.
My page directive in aspx is as follows
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="MyProject_UI._Default" %>
I am using VS 2008. Any idea how to get rid of this?
Try using CodeFile instead of CodeBehind. The latter is a hold-over from .NET 1.1.
Also, make sure the namespaces match up between the markup and the code. Do a test compile to be sure.
I have seen this on occasion when I edit a page. When it happens to me, I close the files and open them again and it seems to fix itself.
This will happen if you are trying to include your control in LayoutTemplate. For example if you are using an asp label in a login control you have converted to a LayoutTemplate.
<asp:Login ID="userLogin" runat="server">
<LayoutTemplate>
<!--Username and password controls-->
<asp:Button ID="btnLogin" CommandName="Login" runat="server" Text="Login" />
<asp:Label ID="lblAlert" runat="server"></asp:Label>
</LayoutTemplate>
So your lblAlert will not show up on the code behind take it out of the layouttemplate or use a loop to find the control within the layout object.
var mylabel = (Label)userLogin.FindControl("lblAlert");

Aspx Property Interpolation

I'm a bit new to .Net development, been working in Java for some time now. I have an aspx page and we need to externalize some strings to make it more flexible.
If I have a table somewhere and there is just a string sitting outside an asp tag, I can replace it so that
<th> Specific Foo String </th>
becomes
<th> <%= Strings.foo %> </th>
and everything is fine, the problem I'm running into is how do you do this kind of interpolation on an asp tag property
I tried changing
<asp:Label runat="server" ID="lblFoo" Text="Specific Foo String Entry" />
to
<asp:Label runat="server" ID="lblFoo" Text='<%= Strings.foo %> Entry' />
and
<asp:Label runat="server" ID="lblFoo" Text='<%#Eval("Strings.foo") %> Entry' />
but neither worked. Is what I'm doing not possible in the aspx file, I know that I can simulate this by rewriting their properties in the code behind, but that's a level of overhead I'd rather not deal with.
Thanks
I think you are looking to do this:
<asp:Label runat="server" id="label1" Text='<%# Strings.Foo + " Entry"%>' />
Then in your code behind (most likely in your OnPageLoad) you need to call
if(!Page.IsPostBack) Page.DataBind();
You need to be cautious however as calling DataBind on controls like textboxes or any labels that may have changed due to logic in the code behind will have their values overwritten with the bound values. Checking that you are not on a post back can help with this, but there are still gotchas.
Also note that I had to move the " Entry" text into the binding statement. If it is placed outside the last '%>' then the binding does not work and it will spit out:
<%# Strings.foo %> Entry
In the codebehind of the page you would do this:
lblFoo.Text = Strings.foo + " Entry";
A good place to put this code would be in the overriden OnLoad method but that is simply a suggestion as I am unfamiliar with your application and the life cycle needs of your page.
If you want to do all this in the aspx page then simply do this:
<span><%= Strings.foo %> Entry</span>
as a Label renders as a span anyhow.
If your objective is an HTML table of strings, then you can create either a ListView or a GridView and DataBind to that. It would save you the trouble of writing out all of your properties and will also produce the correct table tags for the data.
Without knowing more about your data, I cannot provide a detailed code snippet.
You're talking about resources. Read Basic Instincts Resources and Localization in ASP.NET 2.0 which shows you the built in resource editor, and how to use the "<%$ ... %>"-binding, or using meta:resourceKey attribute.

ASP.net Inline Expression Issue

I can't seem to figure out why this does not work below. I need to bind the text box to a value from an inline expression. Seems like a simple thing right? But neither of these work. Any ideas? Thanks in advance.
<asp:textbox id="tbName" runat="server" Text='<%# Eval("test") %>' />
<asp:textbox id="tbName" runat="server" Text='<%= "test" %>' />
Edit:
I should mention that this page has no code behind and only the following directives at the top.
<%# Import Namespace="System" %>
<%# Import Namespace="System.Web" %>
<%# Page Language="C#" %>
Edit:
The only workable solution that I could come up with short of adding a code behind is adding an inline server script, like this one. I wish I knew why the inline expressions won't work unless you're in a data binding context.
<script language="C#" runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
tbName.Text = "test";
}
</script>
In the Page_Load of you will have to make a call to Page.DataBind() for
<asp:textbox id="tbName" runat="server" Text='<%# Eval("test") %>' />
to work.
<%= %> is a shortened response.Write() and is never valid as an attribute, for any server tag.
<%# %> can be used, only if the conatainer is databound (the page in your case).
<%$ %> can be used to access data in resources files.
EDIT: You can also take a look at How to 'bind' Text property of a label in markup which is a smimilar question.
As stated, <%= %> is illegal anywhere within a server control declaration, except where inner markup is being parsed as content (eg <ItemTemplate> within a Repeater).
<%# %> is valid as an expression for control properties, as these expressions will be evaluated when DataBind() is called on the control.
Your use of Eval() looks a little suspect though. Per the example, Eval() will use the current Page object as the binding context, which means that the value of the public property named "test" will be bound to when DataBind() is called. Unless you actually have this property defined on the Page class, the expression will never evaluate to anything.
Eval() is mainly intended for use in expressions within controls such as Repeater, GridView, ListView, etc, where there is a list of data items being bound using templates, and you need a method to be able to access the properties of the current data item.
For all other controls, just use normal code expressions inside a data-binding expression - it's much faster, and more intuitive than Eval(), which relies on runtime reflection.
If you want a more clever alternative using <%$ %> syntax that avoids data-binding altogether, go here:
http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx
Use <asp:textbox id="tbName" runat="server" Text='<%# Eval("test") %>' />
and set tbName.DataBind(); in page load event.
For those who are searching for more info about inline expressions, refer to the following links.
ASP.net have the following inline expressions
Embedded code blocks <% ... %>
Displaying expression <%= ... %>
Directive expression <%# ... %>
Data-binding expression <%# ... %>
Expression builder <%$ ... %>
Server-side comments block <%-- ... --%>
You might need the namespace for the textbox control
<%# Import "System.Web.UI.WebControls" %>
Try adding runat="server" to the server elements.
Otherwise, this element will not be processed at server.
EDIT: Actually, "its correct" that this doesn't work; code <%=...%> cannot be evaluated in a server tag, only expressions like for instance <%$ Resources: h1 %>
<asp:textbox id="tbName" runat="server"><%="test"%></asp:textbox>

ASP.NET cant access datatable created in Page load from inline coding

In my Page_Load event of codebehind file, I am loading data in to a datatable.In my .aspx page I am having some inline coding,I want to display some data from this datatable.But when i am running the program,It is showing an error like "Error 64 Use of unassigned local variable 'dtblChild' "
dtblChild is my DataTable Object
Is Page_Load in codebehind executes after loading the form elements ?
Inline Code executes during the Render stage.
in the lifecycle of a page, Render happens much later than Load
Yes, the page load executes after all of the server controls have been loaded into memory, but you have to ensure that the datatable is repopulated on each refresh if you're going to use it.
I think your question indicates some deeper problems with the way you're binding to the page.
Can you post some code?
Try using a repeater control or datagridview rather than <% %> bee stings for this. Too much inline-code doesn't mix very well with code behind files: you can get unexpected results. It can work if you really know what you're doing, but you have to be careful and I wouldn't recommend it for anyone new to ASP.Net.
I also recommend that you take some time and become very familiar with the ASP.Net Page Lifecycle.
This is my inline coding
</tr>
<%
foreach (DataRow dr in dtblChild.Rows)
{
%>
<tr><td>Thissss</td></tr>
<%
}
%>
in my code behind Page_Load ,i am populating Data to a DataTable object (dtblChild)
The more "ASP.Net-ish" way to do this is like this:
<asp:Repeater ID="MyRepeater" runat="server" DataSource="dtblChild">
<ItemTemplate>
<tr><td>Thisss</td></tr>
</ItemTemplate>
</asp:Repeater>
You probably also need to declare an ObjectDatasource to wrap your datatable to make it compatible with the repeater.
Bind your dtblChild to a repeater (or DataGrid) as suggested above. It will be easier to maintain. Then populate the DataTable in a separate function and bind it to the repeater. Call that function in Page_Load when you need to.
<table>
<asp:Repeater ID="rptSearchResults" runat="server">
<ItemTemplate>
<tr>
<td><%#DataBinder.Eval(Container.DataItem, "ColumnName") %></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
function LoadData()
{
rptSearchResults.DataSource = dtblChild;
rptSearchResults.DataBind();
}

Resources