Does ASP.NET have variables and procedures like ASP? - asp.net

I came across a question here which had loops in ASP.NET
<%for (int i = 0; i < 10; i++) %>
This actually did work in ASP.NET. I then investigate if ASP.NET has variables like ASP but I could not find any solid answer.
A demo of asp variable is here
<%
dim name
name="Donald Duck"
response.write("My name is: " & name)
%>

Yes, but (in webforms anyway) it is there mainly for compatibility with old code and you should avoid using it that way. Includes, especially, will not work as you expect, as each file is compiled separately and includes are processed at runtime rather than compile time... you can use them for html, but not so much for code.
The new options of Master pages, custom and user controls, data binding, and other features are much better mechanisms for building your pages. User controls, especially, are too often overlooked.
What you can do, for simple pages at least, is put one big server-side script block at the top of the page:
<%# Page ... %>
<script runat="server" ... >
Public Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
'...
End Sub
'Other variables and methods can go in here
</script>
<html>
<body>
<form runat="server" ...>
</form>
</body>
</html>

Related

ASP.NET VB Page_Load not firing

Getting straight to the point, I've been searching around and can't find a solution to this. I have an ASP.NET web page with a VB code behind that isn't entering the Page_Load Sub.
I've read suggestions regarding adding "Handles Me.Load" to the Sub or checking the AutoEventWireup(tried setting it true, it's currently set to false).
I'm not finding anything so any help is appreciated in advance. Below is some of the code.
Front End:
<%# Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/MasterPage.Master" CodeBehind="ThisPage.aspx.vb" Inherits="Project.ThisPage" %>
<asp:Content ID="Content" ContentPlaceHolderID="ContentPH" runat="server">
<%-- insert content here --%>
</asp:Content>
Back End:
Partial Public Class ThisPage
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Insert logic here
End Sub
End Class
I assume other code shouldn't be necessary as the only thing happening is some variables are being set and assigned to a control that's on the page. If that's not the case I can add more. I tried setting a break point and it's just never entering the sub.
If this is a partial class, the aspx page should inherits from the base class. Suppose the base class is Base1, then try change the .aspx file line
Inherits="Project.ThisPage"
to
Inherits="Base1"
This happened to me today. It turned out that a colleague committed an .aspx file that had a call to a code-behind function that didn't exist.
A broken commit in other words.
I pulled the code and it built without errors in VS2015 but when the broken page was due to load, the browser reported that it couldn't find it. A breakpoint in page_load wasn't hit. There was nothing to debug.
It took me a while to figure it out (which is how I found myself here), so I'm adding this answer in case someone else has the same problem.
I had just upgraded to Windows 8.1 from Windows 7 and Visual Studio selected the wrong project in the solution as the StartUp project. Selecting the correct project resolved the issue.

ASP.NET: Get value of literal.text after page load?

I'm trying to use the following code to get the text value of a literal so that I can pass it to the next page using PreviousPage, but the string is empty, I think it clears the values after the Page_Init stage.
Public ReadOnly Property SendText() As String
Get
Return literal1.Text
End Get
End Property
Is there a way around this?
Im trying to access the data on the next page using:
<%# PreviousPageType VirtualPath="~/Spacing.aspx" %>
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
litTables.Text = PreviousPage.SendText
End Sub
Even better would be if I could set SendText to the HTML contents of a whole div, but the only way I see to access this is using the JavaScript document.getElementById("tables").innerHTML, but I don't see how I could incorporate that into the ReadOnly Property using Get.
I'm using Visual Studio Express For Web 2012.
This isn't really the way you would pass data between pages in an ASP.NET application. The recommended way would be to POST the data or pass it via the URL.
The data I need to transfer is:
<div id="tables">
<asp:Literal ID="lit1" runat="server" ValidateRequestMode="Disabled"></asp:Literal>
<asp:Literal ID="lit2" runat="server"></asp:Literal>
<asp:Literal ID="lit3" runat="server"></asp:Literal>
</div>

Caching a dynamically/programmatically added user control

I'm trying to learn about caching, and in particular, partial caching using controls.
My website is running slow on certain pages, so caching as much as possible will be helpful.
Having run a number of experiments from code I have found on SO and various other Google results, I am running into an issue with dynamically added controls.
I have set up a simple page, containing this code:
<%# Page Language="VB" Debug="true" %>
<%# Register TagPrefix="controls" TagName="control" Src="~/test/control.ascx" %>
<script runat="server">
Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
Label2.Text = "Present Time: "
Label2.Text += DateTime.Now.ToString()
End Sub
</script>
<html>
<body>
<form id="form1" runat="server">
<div>
<h2 style="color:Red">Output Caching</h2>
<asp:Label ID="Label2" runat="server"></asp:Label>
<controls:control ID='control1' runat='server' />
'------------------------------------------
<hr />
<div id='dyn2' runat='server' />
</div>
</form>
</body>
</html>
The control control.ascx looks like this:
<%# Control Language="VB" ClassName="control" %>
<%# OutputCache Duration="60" VaryByParam="r" %>
<script runat="server">
Sub Page_Load() Handles Me.Load
controlContent.InnerHtml = "Control time: " & DateTime.Now.ToString()
End Sub
</script>
<div id="controlContent" runat="server"></div>
This works well, and gives me a "live" time in the page, whilst the cached control shows me a time which is only updated after 60 seconds has passed, as per the OutputCache declaration.
I can see how I can use this for any application when I need to cache a part of a page and that part is explicitly entered into the page with a <controls> tag. The varyByParam option is useful to me too. (I've yet to investigate varyByCustom!)
However, in some cases I am loading a control into a page, programmatically based on specific needs.
In this case, I use code like this:
Dim theResult As test_control2 = CType(LoadControl("~\test\control2.ascx"), test_control2)
dyn2.Controls.Add(theResult)
This is programmatically adding my second test control, imaginatively entitled control2.ascx into the div with id "dyn2".
With no cache directive header in the control, or it's code-behind,l everything works fine, but I can't cache it (unless I cache the entire page).
However, if I add the cache header as per the control code above, I get this error:
Unable to cast object of type 'System.Web.UI.PartialCachingControl' to type 'test_control2'.
Googling doesn't seem to help me much with this, and investigating the PartialCachingControl types has lead me into further problems!
Can someone tell me what should be doing to enable me to cache these controls?
If it matters, I am coding in VB.net and also using .NET 2.0, so any advice on limitations on this platform would be appreciated too, if applicable.
Ah ha! Finally found another question on SO that helped
How to LoadControl a control that uses VaryByControl OutputCache, specifying values for properties
Basically, I was using the wrong Type when loading the control changin:
Dim theResult As test_control2 = CType(LoadControl("~\test\control2.ascx"), test_control2)
dyn2.Controls.Add(theResult)
to
Dim theResult As PartialCachingControl = DirectCast(LoadControl("~\test\control2.ascx"), PartialCachingControl)
dyn2.Controls.Add(theResult)
Sorted it!

Placing code behind for a DNN page

I'm having troubles finding where I can put code-behind for my dnn pages.
For example:
MyPage.ascx already has
<%# Control language="vb" CodeBehind="~/admin/Skins/skin.vb" AutoEventWireup="false" Explicit="True" Inherits="DotNetNuke.UI.Skins.Skin" %>
which it needs in order to be cast to a skin.
However, I want to be able to add a VB function that is executed on Page_Load, so I made my own code-behind file. But I can't take out the current control (one referencing skin.vb) to put in my own, and you can't have more than one Control.
I also tried embedding the code in a tag, but I need to do some Imports which give me an error saying they must be declared at the beginning of the file etc etc...
Anyone know how to properly add code-behind for DNN pages?
To keep the skin as self-contained as possible, I typically add a script block into the skin's ascx file, below all the HTML in the skin (so it's sort of out of the way), like so:
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
' first page load logic here
End If
' other page load logic here
End Sub
Private Function DoStuff(ByVal input As String) As Integer
' custom function logic
End Function
</script>
If my code requires any additional namespaces, I place them at the top of the skin's ascx file in import statements, like so:
<%# import namespace="System.Data" %>
<%# import namespace="System.Collections.Generic" %>
<%# import namespace="MyCustomLibrary" %>
You should be able to add a codebehind file that, itself, inherits from Skin.
However, I would suggest keeping your skin contained in the .ascx file itself (it is very uncommon for DNN skins to include code). To add the Imports, you can use the # Import directive in the page, instead of the Imports statement in your VB.

Proper use of MasterPages

I've been looking into different methods of implementing masterpages.
Use the masterpage only for layout, include common controls on every page
Include controls on the masterpage, use a masterpage abstract base class and override it's properties in the masterpage class. This caused the masterpage events to no longer wire up. I could probably fix this, but it's a long way to go just for a single textbox value.
use good 'ol Page.Master.FindControl()
I've read that findcontrol should be avoided (uses magic "label1" strings, supposedly uses too many resources) and masterpages are only for layout. If masterpages are only for layout, do I copy and paste common controls across 100's of pages?
What's the best practice that deals with displaying and accessing common site controls (like a search)? Considering the alternatives, using findcontrol to get a masterpage control doesn't seem that bad.
MasterPages are classes just like a normal Page object. That means you can expose internal controls through public properties to allow child Pages to access without having to resort to Master.FindControl(). To do this you just need to set the MasterType property in the page (I think it may work even without setting this but with this you get intellisense support and avoid having to do casts).
Here's a basic example (sorry it's in VB - this is copying and pasting from an old project):
Master page (.master):
<%# Master Language="VB" CodeFile="default.master.vb" Inherits="DefaultMaster" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form runat="server">
<ASP:TextBox ID="Search" RunAt="Server"/>
<ASP:ContentPlaceHolder ID="Content" RunAt="Server"/>
</form>
</body>
</html>
Master code-behind (.master.vb):
Partial Class DefaultMaster : Inherits MasterPage
Public ReadOnly Property SearchBox() As TextBox
Get
Return Search
End Get
End Property
End Class
Accessing page (.aspx):
<%# Page Language="VB" MasterPageFile="default.master" CodeFile="page.aspx.vb" Inherits="ExamplePage" %>
<%# MasterType TypeName="DefaultMaster" %>
<ASP:Content ContentPlaceHolderID="Content" RunAt="Server">
<p>This is some content on the page.</p>
</ASP:Content>
Accessing page code-behind (.aspx.vb):
Partial Class ExamplePage : Inherits Page
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles MyBase.Load
Master.SearchBox.Text = "This page now has access to the master's search box."
End Sub
End Class
Agreeing that master pages are only for layout, would a sensible approach not to farm out the common controls to usercontrols and include them in the master page this way.

Resources