.NET Framework Developer Center > .NET Development Forums > JScript for the .NET Framework > Synchronous callbacks with the .NET 2.0 framework
Ask a questionAsk a question
 

QuestionSynchronous callbacks with the .NET 2.0 framework

  • Monday, February 27, 2006 8:40 AMKars Blom Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    I tried to do a synchronous postback by using useAsync = false for the GetCallbackEventReference method. But when I executed the callback on submit of the form, the form was still submitted before the callback returned. After this I checked out the WebForm_DoCallback javascript function, and I found out that the useAsync parameter doesn't do anything. Here's my solution: (changed code in red

     

    function WebForm_DoCallback2(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync) {
      var postData = __theFormPostData +
        "__CALLBACKID=" + WebForm_EncodeCallback(eventTarget) +
        "&__CALLBACKPARAM=" + WebForm_EncodeCallback(eventArgument);
      if (theForm["__EVENTVALIDATION"]) {
        postData += "&__EVENTVALIDATION=" + WebForm_EncodeCallback(theForm["__EVENTVALIDATION"].value);
      }
      var xmlRequest,e;
      try {
        xmlRequest = new XMLHttpRequest();
      }
      catch(e) {
        try {
          xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(e) {
        }
      }
      var setRequestHeaderMethodExists = true;
      try {
        setRequestHeaderMethodExists = (xmlRequest && xmlRequest.setRequestHeader);
      }
      catch(e) {}
      var callback = new Object();
      callback.eventCallback = eventCallback;
      callback.context = context;
      callback.errorCallback = errorCallback;
      callback.async = useAsync;
      var callbackIndex = WebForm_FillFirstAvailableSlot(__pendingCallbacks, callback);
      if (!useAsync) {
        if (__synchronousCallBackIndex != -1) {
          __pendingCallbacks[__synchronousCallBackIndex] = null;
        }
        __synchronousCallBackIndex = callbackIndex;
      }
      if (setRequestHeaderMethodExists) {
        if (useAsync) {
          xmlRequest.onreadystatechange = WebForm_CallbackComplete;
        }

        callback.xmlRequest = xmlRequest;
        xmlRequest.open("POST", theForm.action, useAsync);
        xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xmlRequest.send(postData);
        if (!useAsync) {
          WebForm_CallbackComplete();
        }

        return;
      }
      callback.xmlRequest = new Object();
      var callbackFrameID = "__CALLBACKFRAME" + callbackIndex;
      var xmlRequestFrame = document.frames[callbackFrameID];
      if (!xmlRequestFrame) {
        xmlRequestFrame = document.createElement("IFRAME");
        xmlRequestFrame.width = "1";
        xmlRequestFrame.height = "1";
        xmlRequestFrame.frameBorder = "0";
        xmlRequestFrame.id = callbackFrameID;
        xmlRequestFrame.name = callbackFrameID;
        xmlRequestFrame.style.position = "absolute";
        xmlRequestFrame.style.top = "-100px"
        xmlRequestFrame.style.left = "-100px";
        try {
          if (callBackFrameUrl) {
            xmlRequestFrame.src = callBackFrameUrl;
          }
        }
        catch(e) {}
        document.body.appendChild(xmlRequestFrame);
      }
      var interval = window.setInterval(function() {
        xmlRequestFrame = document.frames[callbackFrameID];
        if (xmlRequestFrame && xmlRequestFrame.document) {
          window.clearInterval(interval);
          xmlRequestFrame.document.write("");
          xmlRequestFrame.document.close();
          xmlRequestFrame.document.write('<html><body><form method="post"><input type="hidden" name="__CALLBACKLOADSCRIPT" value="t"></form></body></html>');
          xmlRequestFrame.document.close();
          xmlRequestFrame.document.forms[0].action = theForm.action;
          var count = __theFormPostCollection.length;
          var element;
          for (var i = 0; i < count; i++) {
            element = __theFormPostCollectionIdea;
            if (element) {
              var fieldElement = xmlRequestFrame.document.createElement("INPUT");
              fieldElement.type = "hidden";
              fieldElement.name = element.name;
              fieldElement.value = element.value;
              xmlRequestFrame.document.forms[0].appendChild(fieldElement);
            }
          }
          var callbackIdFieldElement = xmlRequestFrame.document.createElement("INPUT");
          callbackIdFieldElement.type = "hidden";
          callbackIdFieldElement.name = "__CALLBACKID";
          callbackIdFieldElement.value = eventTarget;
          xmlRequestFrame.document.forms[0].appendChild(callbackIdFieldElement);
          var callbackParamFieldElement = xmlRequestFrame.document.createElement("INPUT");
          callbackParamFieldElement.type = "hidden";
          callbackParamFieldElement.name = "__CALLBACKPARAM";
          callbackParamFieldElement.value = eventArgument;
          xmlRequestFrame.document.forms[0].appendChild(callbackParamFieldElement);
          if (theForm["__EVENTVALIDATION"]) {
            var callbackValidationFieldElement = xmlRequestFrame.document.createElement("INPUT");
            callbackValidationFieldElement.type = "hidden";
            callbackValidationFieldElement.name = "__EVENTVALIDATION";
            callbackValidationFieldElement.value = theForm["__EVENTVALIDATION"].value;
            xmlRequestFrame.document.forms[0].appendChild(callbackValidationFieldElement);
          }
          var callbackIndexFieldElement = xmlRequestFrame.document.createElement("INPUT");
          callbackIndexFieldElement.type = "hidden";
          callbackIndexFieldElement.name = "__CALLBACKINDEX";
          callbackIndexFieldElement.value = callbackIndex;
          xmlRequestFrame.document.forms[0].appendChild(callbackIndexFieldElement);
          xmlRequestFrame.document.forms[0].submit();
        }
      }, 10);
    }

All Replies

  • Friday, March 17, 2006 11:41 PMRok YuModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Was there a question, or is this just an FYI.
  • Monday, April 17, 2006 2:24 PMMarcDModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    His first paragraph stated what the problem was, and what the changes in red were :) . Thanks OP
  • Thursday, August 28, 2008 11:02 AMaganariman Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
      thank you for your solution. I also saw some methods to pass  by this problem like inserting a specific script into head of the aspx, look here: http://weblogs.asp.net/bleroy/archive/2005/12/15/making-callbacks-and-atlas-synchronous-or-how-to-shoot-yourself-in-the-foot.aspx.
    But if the problem with useAsync boolean parameter is MS's bug, didn't they publish any patch or some solution to make this parameter work? Is somebody have information about it? Life will be much more easy if we just pass one bool parameter(useAsync). not to change microsofts scripts by hand.
    • Edited byaganariman Thursday, August 28, 2008 11:04 AMedited
    •  
  • Thursday, August 28, 2008 6:35 PMBertrand Le Roy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    This is actually by design. In order not to block the UI of the browser, this parameter doesn't actually do the request synchronously but makes sure the requests are queued and only one is going on at any given time. The effect is pretty much the same, except that the end-user can still use the browser UI while the request is going on and he won't have to kill the process if the server fails to respond or the network connection falls.