ASP.NET AJAX and Session Variables - asp.net

I have an ASP.NET (VB.NET) application with 2 pages, a 'main' page and a second 'data-only' page whose only purpose is to be an AJAX data target for the main page, making a database call and rendering the results for a jQuery (AJAX) .get(). I'm using a session variable in the main page that I want to test for the existence of in the data-only page before it makes its DB call and renders the data.
I've tried doing this directly and it fails. From what I've been able to determine so far, the data-only page is unable to detect the session variable until its session is officially started (somehow using session_start, apparently). If this is correct, how do I start a session in the data-only page when it is only accessed via AJAX calls from the main page? I definitely need the data-only page to be session variable-aware. Thanks!
-- Rick
Both pages are ASP.NET. I added a label to the main page to validate (on page_load and on submit of the session value) that the session variable exists and what it is. The data_only page returns a yes or no message (it's always no) if it detects the presense of the session variable.
Page Code - main.aspx:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="main.aspx.vb" Inherits="main" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<form id="form1" runat="server">
<asp:TextBox ID="txt_1" runat="server"></asp:TextBox>
<asp:Button ID="but_1" runat="server" Text="Add Session Variable" /><br />
<asp:Label ID="lbl_1" runat="server"></asp:Label><br /><br />
<asp:Button ID="but_2" runat="server" Text="Get Data" />
<asp:Label ID="lbl_2" runat="server"></asp:Label>
</form>
<script type="text/javascript">
$(document).ready(function () {
$('#but_2').on('click', function (event) {
event.preventDefault();
$.get("data_only.aspx", function (data) {
$('#lbl_2').text(data);
});
});
});
</script>
</body>
</html>
Code-Behind - main.aspx:
Partial Class main
Inherits System.Web.UI.Page
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
Call Check_Session()
End Sub
Protected Sub but_1_Click(sender As Object, e As System.EventArgs) Handles but_1.Click
Session("var1") = txt_1.Text
Call Check_Session()
End Sub
Private Sub Check_Session()
Dim strSession = Session("var1")
If strSession Is Nothing Then
lbl_1.Text = "No Session variable."
Else
lbl_1.Text = "Session Variable = " & strSession
End If
End Sub
End Class
Page Code - data_only.aspx:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="data_only.aspx.vb" Inherits="data_only" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title></title>
</head>
<body></body>
</html>
Code-Behind - data_only.aspx:
Partial Class data_only
Inherits System.Web.UI.Page
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
Dim strSession = Session("var1")
If strSession Is Nothing Then
Response.Write("No session variable.")
Else
' Database call occurs here
Response.Write("Success! Get data here.")
End If
Response.End()
End Sub
End Class

Maybe you could try using a "master class" for both pages i.e both pages inherit from your master class (which in turn from Inherits System.Web.UI.Page) that has all the session handling logic.

Just to clarify and narrow the scope, all .aspx pages are session aware by default and I'm pretty sure that this is not your problem.
First of all make sure that you are using the correct url for the GET call from Ajax, and you can make sure of that by using Chrome developer tools (Network tab) and observer the exact url that Ajax calls. Maybe you need to add "/" before your page url or you need to specify the folder name if it's not in the same folder, like: "/otherFolder/page.aspx".

Related

Process Bar With Process Completion Messages

I am Executing Multiple store procedures on Button click event of my .aspx page
On each Procedure Execution i have to show a message on Process baar that
process 1 is completed.
process 2 is completed.
process 3 is completed.
please help in this
One way is to use an Update Panel in conjunction with Ajax Timer.
The following article may be useful.
http://msdn.microsoft.com/en-in/library/cc295400.aspx
The example given in the article shows you how to update a label in the Update Panel with current server time on the timer event. You can easily adapt the code to your needs and show whatever message you want to show instead of server time.
EDIT
As requested here is some sample code.
Add a new aspx file to your application and name it Test2.aspx
Replace the contents of aspx file as given below.
Run the application and see the sample code working.
Customize the DoWorkAsync method to suit your needs.
Run application and test your modified code.
The ASPX file:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Test2.aspx.vb" Inherits="Test2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Asynchronous Update Demo</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" ID="ScriptManager1">
</asp:ScriptManager>
<asp:UpdatePanel runat="server" ID="UpdatePanel1">
<ContentTemplate>
<asp:Timer runat="server" ID="Timer1" Interval="1000" />
<asp:Button ID="Button1" runat="server" Text="Start" /><br />
<asp:Label runat="server" Text="Click Start button to being processing." ID="Label1" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Code behind file:
(pay attention to inline comments)
Partial Class Test2
Inherits System.Web.UI.Page
Private MyAsyncProcessor As AsyncProcessor
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Session("MyAsyncProcessor") IsNot Nothing Then
' we are still processing.. so extract the reference of our class back from session variable
Me.MyAsyncProcessor = Session("MyAsyncProcessor")
End If
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
' this event is fired everytime a timer ticks.
If MyAsyncProcessor IsNot Nothing Then
Label1.Text = MyAsyncProcessor.StatusMessage
If Not MyAsyncProcessor.IsProcessing Then
MyAsyncProcessor = Nothing
Session.Remove("MyAsyncProcessor")
Timer1.Enabled = False
End If
End If
End Sub
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Label1.Text = ""
Button1.Enabled = False
Timer1.Enabled = True
MyAsyncProcessor = New AsyncProcessor
MyAsyncProcessor.Start()
Session("MyAsyncProcessor") = MyAsyncProcessor 'save reference in a session variable
End Sub
End Class
Public Class AsyncProcessor
Public IsProcessing As Boolean
Public StatusMessage As String
Public Sub Start()
Dim th As New Threading.Thread(AddressOf DoWorkAsync)
th.Start()
End Sub
Private Sub DoWorkAsync()
' *** Replace this code with whatever work you want to do ***
' Set IsProcessing=True at beginnning of task and set it to False when exitting.
' Update the StatusMessage at regular intervals.
IsProcessing = True
For i = 1 To 10
'' this sleep is only to simulate a long going task
Threading.Thread.Sleep(1000)
StatusMessage &= String.Format("Task #{0} completed... <br>", i)
Next
StatusMessage &= "All tasks completed."
IsProcessing = False
End Sub
End Class
Another way is to delegate the work to a page in an iframe. On the iframe page, as your code is processed, you can update a Session variable to contain 'Finished Processing first step' (or whatever) and use PageMethods on the parent page to call a Web Method that gets the value of the session being updated by the code on the page in the iframe.

Understanding UpdatePanels

I am trying to understand UpdatePanels and best practise for using them.
I am using .Net4.0 with VB.Net.
The idea is to create a conversation app for a clients website and so I have control called Convo.ascx. Code added below.
<asp:UpdatePanel runat="server">
<ContentTemplate>
<h2>Conversation</h2>
<p><asp:Literal ID="lit1" runat="server" /></p>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" />
</ContentTemplate>
</asp:UpdatePanel>
Convo.ascx.vb
Partial Class Convo
Inherits System.Web.UI.UserControl
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
lit1.Text = lit1.Text & "<p>" & TextBox1.Text & "</p>"
End Sub
End Class
On a load page (Default.aspx) I have:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%# Reference Control="~/Convo.ascx" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:scriptmanager ID="Scriptmanager1" runat="server"></asp:scriptmanager>
<div>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Add Conversation" />
<asp:PlaceHolder ID="phConversation" runat="server">
</asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
With Codebehind Default.aspx.vb as
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddConvo()
End Sub
Private Sub AddConvo()
Dim getPh As New PlaceHolder
getPh = CType(Me.FindControl("phConversation"), PlaceHolder)
Dim ucConvo As New Convo
ucConvo = CType(LoadControl("~/Convo.ascx"), Convo)
getPh.Controls.Add(ucConvo)
End Sub
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
AddConvo()
End Sub
End Class
So the Convo I add OnLoad remains on the page after extra as been added been any convo added after load is gone once the button on Convo is hit.
So my question is, how can I have these add and remain? Eventually they will be added to database but right now I am trying to understand UpdatePanels as they will become the foundation for this app.
Is there a very good explanation of multi-use UpdatePanels anywhere?
Thanks in advance
PS, im a hobbiest so only VB responses please
The issue actually isn't with the UpdatePanel, but with ASP.NET. ASP.NET web forms uses a control hierarchy for the entire page, and you are adding the controls to the hierarchy "dynamically". Since you are doing it that way, ASP.NET requires you add the control back into the control hierarchy on every postback to the server. The UpdatePanel is a way to post back to the server, and therefore you must re-add the old user controls and new ones to that hierarchy.
Essentially the UpdatePanel was added to make AJAX easy, but you still have to work within the rules of ASP.NET.

intercept __doPostBack function

According to this post you can intercept the post by overriding this function __doPostBack but it wont work. If I view the generated source I am not able to see the function that is meant to be auto generated and causes asp.net to make the postback.
where is this function? and how do I intercept it?
I'm using asp.net 4 and vs 2012
Default.aspx
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script>
//breaks here as it cant find __doPostBack
var __original = __doPostBack;
__doPostBack = myFunction();
function myFunction() {
alert('intercept');
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server" ></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" />
</div>
</form>
</body>
</html>
Default.aspx.vb
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub form1_Load(sender As Object, e As EventArgs) Handles form1.Load
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim txt As String = TextBox1.Text
End Sub
End Class
An ASP.NET Button renders an <input type="submit" /> to postback the form, and will never use this method. The __doPostBack method is only used for elements that are not input buttons that do not normally cause a POST operation to the server. This is a function that's inside one of the Microsoft's JavaScript file, and only gets rendered out on the client. Common uses for __doPostBack are LinkButton controls, controls that may have AutoPostBack="true", and others.
Also, there may be a call to WebForms_DoPostBack... something named like that that also posts back, but internally calls __doPostBack.
If you are trying to prevent postback on click of your button, attach to the submit event of the form, and cancel the postback operation that way.

ASP .net : register custom control from .vb code

I try to create custom control, loaded dynamically from .vb code.
Here is my custom control "ControlCar" in file "controlcar.ascx"
<%# Control Language="VB" ClassName="ControlCar" %>
<script runat="server">
Private m_car As Car = Nothing
Public Property Car() As Car
Get
Car= m_car
End Get
Set(ByVal value As Car)
m_car = value
End Set
End Property
Protected Sub Panel_OnLoad(ByVal sender As Object, ByVal e As System.EventArgs)
If Me.m_car Is Nothing Then
lit_color.Text = "(m_car Is Nothing)"
Else
lit_color.Text = "color of Me.m_car is (" & Me.m_car.Color & ")"
End If
End Sub
</script>
<asp:Panel ID="panel" OnLoad="Panel_OnLoad" runat="server">
this is a car<br />
color = <asp:Literal ID="lit_color" runat="server"></asp:Literal><br />
<br />
</asp:Panel>
Here is my ASP web page in file "cars.aspx" which use .vb code for events, ...
<%# Page Language="vb" Explicit="true" Inherits="PageBase" Src="/code/cars.vb"%>
<html>
<body>
<!-- Html code here --->
<asp:panel ID="panel_cars" runat="server">
</asp:panel>
</body>
And here is my .vb code in file "cars.vb"
Private Sub CreateCar()
Dim car As Car = new Car()
Dim control As ControlCar = Nothing
control= CType(LoadControl("/code/controlcar.ascx"), ControlCar)
control.Car = car
panel_cars.Controls.Add(control)
End Sub
But it fails, saying 'ControlCar' is unrecognized in cars.vb.
I know it works, if move .vb code in .aspx file and using directive
<%# Register TagPrefix="uc" TagName="ControlCar" Src="/code/controlcar.ascx" %>
But I need to separate .vb code and .aspx code like in my example.
How can I make recognizing 'ControlCar' type (defined in .ascx) in .vb file?
You need to add some kind of reference. You can use a reference directive:
<%# Reference Control="controlcar.ascx" %>.
The control is being dynamically compiled. If you have no reference, the compiler has no idea what you are trying to use.
EDIT:
You may be able to use:
Imports ASP.controlcar_ascx
If the reference must be in the code behind. I have had issues with this in the past though.

jQuery Load Result form another page ASP.NET

i am using this way to bind ASP.NET GridView Without postback.
i want to know what are the problems of this way?
what are the alternative ways?
here is my code :
<input id="btnLoadDIV" type="button" value="button" />
<div id="somediv">
</div>
<script>
$(document).ready(function () {
$("#btnLoadDIV").click(function (e) {
e.preventDefault();
var url;
url = "test.aspx?type=test1";
$("#somediv").load(url);
});
});
</script>
Test.aspx BehindCode Code :
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Request.QueryString("type") = "test1" Then
bindgrid()
End If
End Sub
Test.Aspx markup code :
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</form>
</body>
</html>
thanks. regards.
Some basic things you ought to be aware of:
The page will fully execute it's life cycle even if only part of the page is being updated.
Grid views have a horrible footprint and I haven't used them in a long time because of it.
Potential alternatives:
Use a generic handler (.ashx) for running your ajax requests.
If you really want to use ajax on a grid view you might want to read this: http://mattberseth.com/blog/2007/05/7_simple_steps_to_ajaxenable_y.html
Your way is fine. The only thing I would do differently is I would pass the URL's parameters as second argument to $.load. I just feel it is neater:
$("#somediv").load("test.aspx", {type: "test1"});

Resources