Section 10.3. Maintaining Session State


10.3. Maintaining Session State

Web services are sometimes criticized as being a great technology that has nothing to do with the Web itself. But since .NET web services are seamlessly integrated with ASP.NET (naturally), if you're using ASP.NET, you're able to perform some tricks that enable scenarios that web services technology by itself cannot offer.

With .NET web services, for example, you can maintain session state. And even if you are using Ajax, this session state is still available to you from your Atlas application.

Implementing this is easier than describing it. The EnableSession property of the [WebMethod] attribute does the trickexactly as if you were coding a .NET web method:

 [WebMethod(EnableSession=true)] 

Then you can directly access the ASP.NET Session object and write data to it and read from it. The next code snippet shows code for two functions: one stores the current time in a session, and the other one determines the difference between the current time and the timestamp in the session. If there is no timestamp in the session, -1 is returned.

  [WebMethod(EnableSession = true)] public bool SaveTime() {   Session["PageLoaded"] = DateTime.Now;   return true; } [WebMethod(EnableSession = true)] public double CalculateDifference() {   if (Session["PageLoaded"] == null) {     return -1;   } else {     DateTime then = (DateTime)Session["PageLoaded"];     TimeSpan diff = DateTime.Now.Subtract(then);     return diff.TotalSeconds;   } } 

Now let's return to our application for handling the division of two numbers. When the page with the code from the preceding snippet loads and the SaveTime() method is called, the current time is stored in session state. When division of the two numbers you enter is executed, the time difference is calculated. So it is possible to determine how long a user had the form open before the division is requested.

The following JavaScript code calls the web service method to store the time when the page is first loaded by calling the SaveTime() method. Because we don't need any return value, we can route the callback to a function that doesn't do anything.

 function pageLoad(){   PageMethods.SaveTime(doNothing, doNothing, doNothing); } function doNothing(result) {   //nothing :-) } 

As before, you'll need a callService() method to call the CalculateDifference() web service method. The following code makes two calls to web service methods. The first calculates the time difference between the initial page load and now; the second performs the same math calculation we have been using.

 function callService(f) {   document.getElementById("c").innerHTML = "";   PageMethods.CalculateDifference(     showDifference,     callTimeout,     callError);   PageMethods.DivideNumbers(     parseInt(f.elements["a"].value),     parseInt(f.elements["b"].value),     callComplete,     callTimeout,     callError); } 

Finally, you need some markup to display the time difference. We will use the output <div> container. Note that the return value -1 from the web 196ethod means that there was no timestamp in the session, so no time difference can be displayed:

 function showDifference(result) {   if (result != -1) {     document.getElementById("output").innerHTML =       "The form has been open for " + result + " seconds";   } } 

Example 10-4 shows the complete markup and script you need to implement this example, with changes shown in bold. Note that you must not use EnableScriptComponents="false" here; otherwise, the session management will not work.

Example 10-4. Maintaining session state with Atlas and ASP.NET

 WebServiceSession.aspx <%@ Page Language="C#" %> <%@ Import Namespace="System.Web.Services" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server">   [WebMethod(EnableSession = true)]   public bool SaveTime()   {     Session["PageLoaded"] = DateTime.Now;     return true;   }   [WebMethod(EnableSession = true)]   public double CalculateDifference()   {     if (Session["PageLoaded"] == null) {     return -1;     } else {     DateTime then = (DateTime)Session["PageLoaded"];     TimeSpan diff = DateTime.Now.Subtract(then);     return diff.TotalSeconds;     }   }   [WebMethod]   public float DivideNumbers(int a, int b)   {     if (b == 0)     {       throw new DivideByZeroException();     }     else     {       return (float)a / b;     }   } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">   <title>Atlas</title>   <script language="Javascript" type="text/javascript">   function pageLoad() {     PageMethods.SaveTime(doNothing, doNothing, doNothing);   }   function doNothing(result) {     //nothing :-)   }   function callService(f) {     document.getElementById("c").innerHTML = "";     PageMethods.CalculateDifference(     showDifference,     callTimeout,     callError);     PageMethods.DivideNumbers(       parseInt(f.elements["a"].value),       parseInt(f.elements["b"].value),       callComplete,       callTimeout,       callError);   } function showDifference(result) {     if (result != -1) {     document.getElementById("output").innerHTML =     "The form has been open for " + result + " seconds";     }   }   function callComplete(result) {     document.getElementById("c").innerHTML = result;   }   function callTimeout(result) {     window.alert("Error! " + result);   }   function callError(result) {     if (result == null) {       window.alert("Error!");     } else {       document.getElementById("output").innerHTML =         "<b>" +         result.get_exceptionType() +         "</b>: " +         result.get_message() +         "<br />" +         result.get_stackTrace();     }   }   </script> </head> <body>   <form  runat="server">     <atlas:ScriptManager  runat="server">     </atlas:ScriptManager>     <div>       <nobr>         <input type="text"  name="a" size="2" />         :         <input type="text"  name="b" size="2" />         = <span  style="width: 50px;"></span>       </nobr>       <br />       <input type="button" value="Divide Numbers" onclick="callService(this.form);" />       <br />       <div  style="width: 600px; height: 300px;">       </div>     </div>   </form> </body> </html> 

When the MathService method is called in the browser, you will notice two things that are different from earlier examples. First, the web site sends out a session cookie (unless you specified cookieless session management in the Web.config file). If your browser prompts you before accepting cookies, you will see a dialog box like the one in Figure 10-3). Second, the session data is preserved during calls to the web service (see Figure 10-4).

Figure 10-3. ASP.NET now sends out a session cookie on behalf of the page


Figure 10-4. Using session state to store a time for calculating elapsed time between page load and user request


So far, you've learned about special web services features Atlas offers that would be extremely hard to do with JavaScript alone; the Atlas framework integrates very well with .NET web services, making bridging between the two technologies JavaScript (client) and ASP.NET (server) very convenient.

However, thanks to Atlas, another JavaScript limitation can be overcome: calling web services that reside on another domain.




Programming Atlas
Programming Atlas
ISBN: 0596526725
EAN: 2147483647
Year: 2006
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net