Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 395
  • Last Modified:

Cascading Ajax Call Backs in ASP.Net 2.0

Hello,

I'm wondering if it's possible to loop callbacks with AJAX in ASP.Net 2.0. I've scoured the net and EE's database and found a few crumbs that led nowhere. I'm assuming it's not possible, maybe for security reasons.

This code is based off of the example from this page: http://steveorr.net/articles/Ajax.aspx 

Basically when I push a button on the form, it does a call back that looks like this:
WebForm_DoCallback('__Page',GetCallOutMessage(),MyCallBack3,null,MyErrCallBack,true)

MyCallBack3 Looks Like:
function MyCallBack3(result, context){ProcessCallBackText(result);}

See Included code.

The idea is to increment a number for each loop which works the first time. The number is stored in a hidden field "document.form1.hdnContinueProcess" and starts at 0. The first loop increments to 1 (in the code behind) and displays an unique js alert message correctly. Then, when the javascript executes a repeat call back a few lines later it acts as if it was doing the original call back, perhaps as a cache. This is because the returned data is always the same as the first return no matter what is passed back as the second increment. Also, I put breakpoints in the code behind while running the page in debug. The breakpoints were placed on lines where they would have to be hit if the call back was occurring. The breakpoints were hit on the first iteration, but not on the second or others thereafter. What results is an endless loop of "Merry Christmas", when it should be "Merry Christmas" then "Happy New Year"... etc. (The holidays were in a sample javascript case statement I copied for my testing.)

               case '1': alert('Merry Christmas'); flag.value = "2"; callAgain = true; break;
               case '2': alert('Happy New Year');  flag.value = "3"; callAgain = true; break;

The real life implementation of my idea is to process large chunks of data that could take as much as an hour and have the ASPX form updated with the progress of the process.

Thanks!
function GetCallOutMessage(){
         var hv = document.form1.hdnContinueProcess.value;
         alert("Getting Hidden Value for Call Out [" + hv + "]");
         return hv;
      }
      function ProcessCallBackText(text){
         var temp = new Array();
         temp = txt.split('|');
         var code = temp[0];
         var msg = "";
         try{ msg = temp[1]; }catch(e){alert("Error with message: " + e);};
         var flag = document.form1.hdnContinueProcess;
         var callAgain = false;
         var old = document.form1.txtMessage.Text;
         document.form1.txtMessage.Text = msg + "\r\n" + old;
         alert("Message: " + msg);
         switch (code) {
	         case '1': alert('Merry Christmas'); flag.value = "2"; callAgain = true; break;
	         case '2': alert('Happy New Year');  flag.value = "3"; callAgain = true; break;
	         case '3': alert('Happy Easter');    flag.value = "4"; callAgain = true; break;
	         case '4': alert('Happy Holidays');  flag.value = "5"; callAgain = true; break;
	         default: alert('Welcome [' + code + ']'); callAgain = false; flag.value = 2;
         }
         if(callAgain){
            try{
               alert("Hidden value: " + document.form1.hdnContinueProcess.value);
               eval(document.form1.hdnCallBackCode.value);
            }catch(e){alert("Call again eval failed in javascript.");}
         }else{
            alert("Do not call again.");
         }
      }
 
...
 
document.form1.hdnCallBackCode.value = 
WebForm_DoCallback('__Page',GetCallOutMessage(),MyCallBack3,null,MyErrCallBack,true)
 
...
 
	Public Function GetCallbackResult1() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
		Dim s As String = ""
		Select Case mCallBackEventArg
			Case "Parm"
				s = "The server time is " & Date.Now.ToString
			Case "Test"
				s = "This is a test."
				'Me.txtMessage.Text += "Text Changed " & Date.Now.ToShortTimeString
				If Me.hdnContinueProcess.Value <> "2" Then
					ProcessTest()
				Else
					s = "Test Processed"
				End If
			Case "0", "1", "2", "3", "4"
				Try
					s = (CInt(mCallBackEventArg) + 1).ToString & "|Hello World"
				Catch ex As Exception
				End Try
		End Select
		'
		Response.Expires = -1
 
		Return s
	End Function
 
	Public Sub RaiseCallbackEvent1(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
		Diagnostics.Debug.WriteLine("callback detected on server")
		Diagnostics.Debug.WriteLine("parameter retrieved from client: " & eventArgument)
		'
		' New Code
		mCallBackEventArg = eventArgument
	End Sub

Open in new window

0
NEWIRETECH
Asked:
NEWIRETECH
2 Solutions
 
informaniacCommented:
R u incrementing the value of hdnContinueProcess by 1 in the codebehind?

If yes, I suggest you set it in javascript itself.

document.form1.hdnContinueProcess .value = parseInt(document.form1.hdnContinueProcess .value) + 1
0
 
NEWIRETECHAuthor Commented:
Okay,

Thanks for your inquary Informaniac, but that is not the issue.

I apologize for not including the entire code. I have now simplified the example to its simplest form. Before the code was mixed up in between proprietary code that I could not share.

Now I have a plug-n-play example to show. I have the entire aspx and aspx.vb code behind pasted in the sample "Code Snippet" below. Just take the code and paste it into files "MyPage.aspx" and "MyPage.aspx.vb" and run it.  (I ran it in debug as it's own .Net 2.0 web site in VS 2005.)

There are two buttons. Each perform a different call back. The second button is called "Test Loop". It runs the endless loop, showing the issue that I have described. I have included Javascript alert messages in the different functions of the JS code so you can see how it is working while it runs. The first button just calls back the server time and displays it in a JS alert message box.

My Theory: When the second iteration hits, the response from the first call back has not been cleared. This being the hypothetical case, when the second iteration calls for the call back the browser (I-Explorer) thinks that the first response (that is still in memory) is the response for the second call back and continues as if it worked correctly though the second call back never occurred. This results in an endless loop. If this theory is correct, then there is probably unseen code to clear the call back responce _after_ any custom call back code is ran. This would be like the Page Unload event in the post back cycle that occurs after the Page Load, etc.

My Question: Can you trigger a second call back from the result of a previous call back? Could something like Window.Timer do it? I should try that.
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="MyPage.aspx.vb" Inherits="MyPage" %>
 
<!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 runat="server">
    <title>Ajax Test</title>
    <script type="text/javascript">
    
      function ProcessCallBackText(text){
         var code = text;
         var flag = document.form1.hdnContinueProcess;
         var callAgain = false;
         alert("Returned Code: " + code);
         switch (code) {
	         case '1': alert('Merry Christmas'); flag.value = "2"; callAgain = true; break;
	         case '2': alert('Happy New Year');  flag.value = "3"; callAgain = true; break;
	         default: alert('Welcome [' + code + ']'); callAgain = false; flag.value = 2;
         }
         if(callAgain){
            try{
               alert("Hidden value: " + document.form1.hdnContinueProcess.value);
               eval(document.form1.hdnCallBackCode.value);
            }catch(e){alert("Call again eval failed in javascript.");}
         }else{
            alert("Do not call again.");
         }
      }
      function GetCallOutMessage(){
         var hv = document.form1.hdnContinueProcess.value;
         alert("Getting Hidden Value for Call Out [" + hv + "]");
         return hv;
      }
    
    </script>
</head>
<body>
   <form id="form1" runat="server">
      <asp:HiddenField ID="hdnContinueProcess" runat="server" />
      <asp:HiddenField ID="hdnCallBackCode" runat="server" />
     <div>
         <button runat="server" id="btn">Get Time</button> <button runat="server" id="btnTestLoop">
            Test Loop
         </button>
      </div>
   </form>
</body>
</html>
 
... Code Behind: ...
 
Imports System.Diagnostics
 
Partial Class MyPage
	Inherits System.Web.UI.Page
	Implements ICallbackEventHandler
 
	Private mEventArgument As String
 
	Public Function GetCallbackResult1() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
		If mEventArgument = "Parm" Then
			Return ("The server time is " & Date.Now.ToString)
		Else
			Return mEventArgument
		End If
	End Function
 
	Public Sub RaiseCallbackEvent1(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
		Debug.WriteLine("callback detected on server")
		Debug.WriteLine("parameter retrieved from client: " & eventArgument)
		mEventArgument = eventArgument
	End Sub
 
	Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
		'Define JavaScript functions that will recieve the result
 
		Dim sCallBack As String = _
		  "function MyCallBack(result, context){alert(result);}"
 
		Dim sCallBackLoop As String = _
		 "function MyCallBackLoop(result, context){ProcessCallBackText(result);}"
 
		Dim sErrCallBack As String = _
	 "function MyErrCallBack(result,context){alert(result);}"
 
		'Output the JavaScript functions to the page
		Page.ClientScript.RegisterClientScriptBlock(Me.GetType, _
		  "MyCallBack", sCallBack, True)
 
		Page.ClientScript.RegisterClientScriptBlock(Me.GetType, _
		  "MyErrCallBack", sErrCallBack, True)
 
		Page.ClientScript.RegisterClientScriptBlock(Me.GetType, _
		  "MyCallBackLoop", sCallBackLoop, True)
 
		'Attach button's client event to the JavaScript functions
		btn.Attributes("OnClick") = _
		 Page.ClientScript.GetCallbackEventReference(Me, _
		 "'Parm'", "MyCallBack", "null", "MyErrCallBack", True)
 
		' ...
 
		Dim callBackCode1 = Page.ClientScript.GetCallbackEventReference(Me, _
			  "GetCallOutMessage()", "MyCallBackLoop", "null", "MyErrCallBack", True)
		Me.hdnCallBackCode.Value = callBackCode1
		btnTestLoop.Attributes("OnClick") = callBackCode1
		'
		If Not Page.IsPostBack Then
			'Outputs the time the page was initially rendered
			Response.Write("Page Rendered at " & Date.Now.ToString)
		End If
 
		If Not (IsPostBack()) Then
			'
			mEventArgument = ""
			Me.hdnContinueProcess.Value = "1"
			'
		End If
 
	End Sub
End Class

Open in new window

0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now