Problem calling webservice from onUnLoad function?

J

James Radke

Hello,

I have an asp.net web page (1.l Framework) which has an onUnLoad function
defined in the body.

From this function I want to call a webservice, which I have defined using
the webservice.htc in a div style attribute. I use this webservice call
technique on many other pages without any problems.

However, when I call the webservice from within the onUnload javascript
function, it never seems to actually get to the webservice? Why would that
be? Has the DIV already been removed from memory or something?

I don't receive any errors, it just never gets to my webservice
function.....

Thanks!

Jim
 
B

bruce barker

the soap behavior is not a synchronous routine. unload is the last
javascript call before the page is torn down and all scripts are stopped and
destroyed. this will not work unless you cancel the unload by returning
false.

also the lastest security settings for IE disable the soap behavior, so I
would not count on using it too much.

-- bruce (sqlwork.com)
 
J

James Radke

What happens if I us the synchronous call, by setting the ASYNC property to
false? Shouldn't that work?

Jim
 
S

Steven Cheng[MSFT]

Thanks a lot for Bruce's informative suggestions.

Hi Jim,

I think Bruce's suggestion is quite correct. And after some research, I
found that the callService method in the "webservice.htc" file is by
default set as asynchronous, so I think that this is why your calling in
the page's unload will not actually posted to the webservice. I found that
we can make the service all as synchronous by setting its "async" property
as "false". For example:

document.all("divWS").useService("http://localhost/Myservice/MyService.asmx?
WSDL","LogCall");
document.all("divWS").LogCall.async = false;
document.all("divWS").LogCall.callService("LogCall","steven");

I've tested on my side via the above code in a page's unload event and it
works well. Please also have a try to see whether it works for you. Thanks.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
S

Steven Cheng[MSFT]

Hi Jim,

Thanks for your followup. You meant that your code is exactly the same as
mine which has set the "async"as
false and still not work? If so, I'm thinking whether the problem is
something concerned with the certain webservcie. Would you try creating
another new simple webservice and try to call it via the sychronous style
javascript code to see whether it works? Here are webservice class and
jscript code I used for testing, you may have a try on them to see whether
they work:
----------------------------------websrevice
class------------------------------
public class MyService : System.Web.Services.WebService
{
public MyService()
{
InitializeComponent();
}

#region Component Designer generated code
private IContainer components = null;

private void InitializeComponent()
{
}


protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}

#endregion
[WebMethod]
public void LogCall(string caller)
{
StreamWriter w = File.AppendText(Server.MapPath("logs/log.txt"));
Log(caller + "called LogCall Service",w);
w.Close();
}

public void Log (String logMessage, TextWriter w)
{
w.Write("\r\nLog Entry : ");
w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
DateTime.Now.ToLongDateString());
w.WriteLine(" :");
w.WriteLine(" :{0}", logMessage);
w.WriteLine ("-------------------------------");
// Update the underlying file.
w.Flush();
}


}
-----------------------------page used to call
webservice--------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>CallWS</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
<script language="javascript">
function CallLog()
{

document.all("divWS").useService("http://localhost/Myservice/MyService.asmx?
WSDL","LogCall");
document.all("divWS").LogCall.async = false;
document.all("divWS").LogCall.callService("LogCall","steven");

alert('unload');
}


</script>
</HEAD>
<body onunload="CallLog();">
<form id="Form1" method="post" runat="server">
<table width="100%" align="center">
<tr>
<td>Call WebService</td>
</tr>
<tr>
<td>
<div id="divWS" style="BEHAVIOR: url(webservice.htc)">
LogService
</div>
</td>
</tr>
<tr>
<td><INPUT type="button" value="CallService" name="btnCall"
onclick="CallLog()" /></td>
</tr>

</table>
</form>
</body>
</HTML>

---------------------------------------------------------------------
Hope these help.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
J

James Radke

Steven,

It's the strangest thing. When I place a button on my webform like this:

<td><INPUT type="button" value="CallService" name="btnCall"
onclick="checkclose()" /></td>

The javascript executes, and I get into the webservice every time (I placed
debug.writeline statements within the webmethod to verify) I click the
button. Then, when I close the page (after clicking the button), the
onlunload function also successfully gets into the webmethod.

HOWEVER; if I never click the button first, the onunload does call my
javascript (placed an alert in the javascript); and the statement for the
webservice is executed, but the debug.writeline statements are never
executed which shows that I never reach the webmethod?

Also, my webmethod is a little different that yours; it is simply:

<WebMethod(EnableSession:=True)> _
Public Sub TestAbandonSession()
debug.writeline("At beginning of TestAbandonSession")
Session.Abandon
debug.writeline("At end of TestAbandonSession")
End Sub

What I am trying to do is capture the closing of the browser so that I can
abandon the session; which will trigger the Session_End in the Global.ASAX
file so that I can decremrent the number of logged in users by one in my
performance counters. Again; when I click the test button I created,
everything works fine.

Any other ideas?

Jim


Steven Cheng said:
Hi Jim,

Thanks for your followup. You meant that your code is exactly the same as
mine which has set the "async"as
false and still not work? If so, I'm thinking whether the problem is
something concerned with the certain webservcie. Would you try creating
another new simple webservice and try to call it via the sychronous style
javascript code to see whether it works? Here are webservice class and
jscript code I used for testing, you may have a try on them to see whether
they work:
----------------------------------websrevice
class------------------------------
public class MyService : System.Web.Services.WebService
{
public MyService()
{
InitializeComponent();
}

#region Component Designer generated code
private IContainer components = null;

private void InitializeComponent()
{
}


protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}

#endregion
[WebMethod]
public void LogCall(string caller)
{
StreamWriter w = File.AppendText(Server.MapPath("logs/log.txt"));
Log(caller + "called LogCall Service",w);
w.Close();
}

public void Log (String logMessage, TextWriter w)
{
w.Write("\r\nLog Entry : ");
w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
DateTime.Now.ToLongDateString());
w.WriteLine(" :");
w.WriteLine(" :{0}", logMessage);
w.WriteLine ("-------------------------------");
// Update the underlying file.
w.Flush();
}


}
-----------------------------page used to call
webservice--------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>CallWS</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
<script language="javascript">
function CallLog()
{

document.all("divWS").useService("http://localhost/Myservice/MyService.asmx?
WSDL","LogCall");
document.all("divWS").LogCall.async = false;
document.all("divWS").LogCall.callService("LogCall","steven");

alert('unload');
}


</script>
</HEAD>
<body onunload="CallLog();">
<form id="Form1" method="post" runat="server">
<table width="100%" align="center">
<tr>
<td>Call WebService</td>
</tr>
<tr>
<td>
<div id="divWS" style="BEHAVIOR: url(webservice.htc)">
LogService
</div>
</td>
</tr>
<tr>
<td><INPUT type="button" value="CallService" name="btnCall"
onclick="CallLog()" /></td>
</tr>

</table>
</form>
</body>
</HTML>

---------------------------------------------------------------------
Hope these help.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
S

Steven Cheng[MSFT]

Hi Jim,

Thanks for your response. According to the situation you mentioned, I've
done a simple test on my side, using the Debug.Write to write some debug
info in the WebMethod. And when I start the webservice via F5 and call it
at clientside in a certain web page, I did encountered the problem you
mentioned. If I load the page first time and close it immediately without
any other operations, the webservice is not called. And after some further
testing, I found that the problem seems caused by the webservice is not
initialize completely at clientside. What I used to call the webservice is
as below:
<script language="javascript">
function CallLog()
{

document.all("divWS").useService("http://localhost/Myservice/MyService.asmx?
WSDL","LogCall");
document.all("divWS").LogCall.async = false;
document.all("divWS").LogCall.callService("LogCall","steven");
}
</script>
</HEAD>
<body onunload="CallLog();">

Notice that the
"document.all("divWS").useService("http://localhost/Myservice/MyService.asmx
?WSDL","LogCall");"
and "document.all("divWS").LogCall.async = false;" are used to intialize
the clientside webservice component. When we directly close the browser
window ,the browser hasn't enought time to complete the intialize
operations, that's why we encountered the problem. Now I change the
clientside code as below:
<script language="javascript">
function InitWS()
{

document.all("divWS").useService("http://localhost/Myservice/MyService.asmx?
WSDL","LogCall");
document.all("divWS").LogCall.async = false;
}

function CallLog()
{

document.all("divWS").LogCall.callService("LogCall","steven");

}

</script>
</HEAD>
<body onload="InitWS()" onunload="CallLog();">

Put the initialize operations in a separate function and called the
function in body's "onload" event. Then only call the

document.all("divWS").LogCall.callService in the unload event. Thus, I
found the webservice is called everytime I closed the browser window.
Please have a try on your side to see whether it also works.

In addition, since you call the webservice(used to notify serverside to
abandom session) in the page's unload event, one thing should be noticed
that the body's "unload" event will be fired not only the browser is closed
but also if user use the "refresh" button on IE browser, so I need also
conside such scenario. Hope this helps.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top