{ return objComplexCustomerType; } In this example code, the web service accepts the custom business object and then returns the value.. This can be helpful in situations where data may
Trang 1} function ComplexScriptCompleteCallback(result) {
alert(“Value: “ + result);
}
</script>
<input type=”button” value=”Click for Complex DataType”
onclick=”ComplexDataTypeCall();” />
<atlas:ScriptManager ID=”Script1” runat=”server”>
<Services>
<atlas:ServiceReference Path=”ComplexWebService.asmx” />
</Services>
</atlas:ScriptManager>
<div>
</div>
</form>
<script type=”text/xml-script”>
<page xmlns:script=”http://schemas.microsoft.com/xml-script/2005”>
<references>
</references>
<components>
</components>
</page>
</script>
</body>
</html>
The code for the complex data type is:
public class cComplexCustomerType {
public cComplexCustomerType() {
} private string _Name;
private string _Address;
public string Name {
get { return _Name; } set { _Name = value;}
} public string Address {
get { return _Address; } set { _Address = value; } }
} The code for the web service is:
[WebMethod]
public cComplexCustomerType AcceptComplexDataType(cComplexCustomerType objComplexCustomerType)
261
Trang 2{ return (objComplexCustomerType);
}
In this example code, the web service accepts the custom business object and then returns the value There is nothing that would stop the web service from using the properties of the business object that is passed or the web service from returning a string as opposed to the custom business object
Interrogation of the custom object returns interesting information The following code will generate the results in Figure 10-5 This figure shows that the Nameand Addressproperties are available along with
an added member — the serverTypeproperty This property defines the type on the server
function ComplexScriptCompleteCallback(result) {
var str = “”;
debug.dump(result);
for(prop in result) str += “Member: “ + prop + “\r\n”;
alert(str);
}
Figure 10-5
A call to debug.dump()on the returned result object produces the output in Figure 10-6 The debug dump()method displays the contents of an object in Atlas This method will be discussed more later in this chapter
Figure 10-6 262
Trang 3Caching Web Ser vices
The data returned from a web service may be cached This can be helpful in situations where data may not be time critical (for example, a web service that returns the weather forecast for a given location) This is performed in NET by setting a value on the CacheDurationof the WebMethod()attribute As you may have previously done when working with web services, Atlas makes it possible to call a cached web service and get the results of a web service call Depending on the data and the time that is required
to perform the calculation, the time saved by caching may be significant when factored over thousands
of possible users
Take a look at some code and the result In this example, you are just going to display the time of each call On the first call, both times that are returned will be the same Subsequent calls will result in the current time being updated and the cached time being the same, while the cached time is not updated until the cache duration is over
This is the code for an aspx page:
<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”CachedWebService.aspx.cs” Inherits=”CachedWebService” %>
<!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>Untitled Page</title>
</head>
<body>
<form id=”form1” runat=”server”>
<input type=”button” id=”btnGetServerTime” value=”Get Server Time”
onclick=”GetServerTime();” />
<script language=”javascript”>
function GetServerTime() {
CachingWebService.GetServerCachedTime(DisplayServerCachedTime);
CachingWebService.GetServerCurrentTime(DisplayServerCurrentTime); }
function DisplayServerCurrentTime(result) {
var ctrl = document.getElementById(“NewTime”);
ctrl.innerText = result;
} function DisplayServerCachedTime(result) {
var ctrl = document.getElementById(“StartTime”);
ctrl.innerText = result;
}
</script>
<atlas:ScriptManager ID=”Script1” runat=”server”>
<Services>
<atlas:ServiceReference Path=”CachingWebService.asmx”
GenerateProxy=”true” />
</Services>
</atlas:ScriptManager>
<br />
Start Call:
263
Trang 4<div id=”StartTime”></div>
<br />
New Time:
<div id=”NewTime”>
</div>
<script type=”text/xml-script”>
<page xmlns:script=”http://schemas.microsoft.com/xml-script/2005”>
<references>
</references>
<components>
</components>
</page>
</script>
</form>
</body>
</html>
In the preceding code, on a button click, two remote calls are made out to the server — a call to the GetServerCachedTimemethod and one to the GetServerCurrentTimemethod The GetServer CachedTimemethod on the server returns the current server time when it is called the first time The result of this call is cached in server memory Subsequent calls are returned the cached result for the next
100 seconds, at which point the next request will generate a new time and a new entry in the server cache
As a result, calls to GetServercurrentTime() will result in the current time of the server being returned while calls to GetServerCachedTime()will result in a value that is up to 100 seconds old The following is the code for a web service:
[WebMethod(CacheDuration = 100)]
public DateTime GetServerCachedTime() {
return(DateTime.Now.ToUniversalTime());
} [WebMethod]
public DateTime GetServerCurrentTime() {
return (DateTime.Now.ToUniversalTime());
}
Atlas uses UTC encoding for dates and time This may create confusion for you if you don’t remember
it Personally, my system is set with the time of GMT – 5 As a result, the times that were coming back were 5 hours off.
Figure 10-7 shows the results of multiple calls to the cached and noncached web services
In Figure 10-7, you will notice the two different time values This shows that calling the cached web ser-vice returns the cached value and the noncached version returns the current value of the DateTime.Now object
264
Trang 5Figure 10-7
Exposing Web Ser vices from a Web Form
All of the examples you’ve explored to this point in this chapter have used a dedicated web service It is also possible to have a web service that is exposed within an internal page of a web application On the surface, it appears that there is no real advantage to this However, there are two advantages to using web services that are exposed by a web form These are:
❑ The page and web service are deployed together There are fewer files to deploy and fewer things that can go wrong
❑ While not having been announced as this is being written, it appears that Microsoft will be adding some special functionality that will be available only to a web service that is called within a web form Given the early status of Atlas, more information will come out about this in the future This next example calls back to a web service on the same aspxpage
The code for the web page is:
<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”InternalWebService.aspx.cs” Inherits=”InternalWebService” %>
<!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>Internal Web Service Page</title>
</head>
<body>
<atlas:ScriptManager ID=”Script1” runat=”server”>
</atlas:ScriptManager>
<form id=”form1” runat=”server”>
<div>
<input type=”button” id=”btn” value=”Call Internal Web Service”
onclick=”CallInternalWebService()” />
265
Trang 6<script language=”javascript”>
function CallInternalWebService() {
PageMethods.CallInternalWebService(InternalCallBack);
} function InternalCallBack(result) {
alert(result);
}
</script>
</div>
</form>
</body>
</html>
In the preceding code, note that the calling convention is not Class.MethodName(), but PageMethods MethodName() PageMethodsis a special class that is used to call the methods internal to a page The code-behind file is shown below Note the addition of the System.Web.Servicesnamespace, which is not typically specified in a code-beside or aspx page The method displayed in the following merely returns a string as an example; however, any number of datatypes can be returned, just like a regular web service and the other examples
using System.Web.Services;
[WebMethod]
public string CallInternalWebService()
{
return (“Internal Web Service Called.”);
}
The result of this is shown in Figure 10-8
Figure 10-8 266
Trang 7Atlas Extensions to JavaScript
Atlas allows for the creation of rich client-side applications that run within the browser To facilitate the creation of these applications, Atlas has created a set of extensions to the type system in JavaScript These extensions provide many of the features of the NET type system to the client-side web browser environment These extensions include namespaces, inheritance, interfaces, enums, support for strings, and arrays
Language Enhancements
JavaScript has been around as a language since the early betas of the Netscape Navigator 2.0 web browser appeared in late 1995 to early 1996 Since then, there have been numerous enhancements to the JavaScript language The latest version of the language is version 1.6 With the shipment of the NET Framework, Microsoft has released a framework that contains a set of base classes that have features across various languages, including Visual Basic, C#, and JavaScript when running native and server-side applications Into this, steps Atlas Atlas provides a set of enhancements on top of JavaScript as it runs in the web browser The next sections look at these enhancements and extensions
Controls
Atlas provides a set of controls, classes, and objects that may be used programmatically in JavaScript
Object
The Objectclass is a client version of the NET System.Objectclass The only method that it imple-ments is the getType(obj)method This method will return the type of the specified object
Array
The Arrayclass is similar in concept to the NET System.Collections.ArrayList()class It has several interesting members such as length, push(), and pop() A small example is
var ary = new Array();
ary.push(47);
alert(“length: “ + ary.length);
In this short example, the user is presented with an alert box with a length of 1
Date
The Dateclass is conceptually similar to a client web browser version of the NET System.DateTimeclass The Dateobject supports a set of methods similar to the Date() class in NET There are methods to create
a date, get various parts of a date, and set the parts of a date For a quick example, it is possible to create a date:
var dt = new Date();
dt.setFullYear(2006, 03, 26);
dt.setHours(10, 12, 13, 5);
alert(“Date: “ + dt.toString());
In the preceding example code, the date that is created is March 26, 2006, 10 hours, 12 minutes, 13 sec-onds, and 5 milliseconds The resulting date is then displayed to the user in an alert()window
267
Trang 8The Numberclass contains several methods There are several methods to parse the content of the num-ber as well as convert it to a string, get the exponential value, and perform other operations
Boolean
The Booleanclass is used for parsing traditional boolean values It implements several methods for creating a boolean If the passed value is a string and would return as boolean, the boolean value is returned
String
The Stringclass is a client web browser version of the NET Stringclass The String()class imple-ments some of the methods that are similar to the String()class in NET Some of the more interesting members of the Atlas String()class are:
❑ indexOf()— The indexOf(string, startingindex)returns the value of the starting loca-tion of the specified string when at the startingindexlocation
❑ lastIndexOf()— The lastIndexOf(string, startingindex)returns the value of the starting location of the last time the specified string is found
❑ substring()— The substring(start, end)returns the substring from the starting location
to the ending location
❑ substr()— The substr(start, length)returns the substring from the starting location of the specified length
❑ toLowerCase()— The lowercase version of the string is returned
❑ toUpperCase()— The uppercase version of the string is returned
RegExp
The RegExpclass is a client web browser version of the NET Regular Expression library The Atlas RegExpclass supports the parse(value)method
Built-In Namespaces
Atlas comes with a number of built-in namespaces and classes for managing data, HTTP communica-tion, user interface design, and other things These are in the Sys.*namespaces The next sections look
at several of the namespaces and their associated classes
Sys.Net.WebRequest
The Sys.Netnamespace provides a set of classes to facilitate HTTP communications between the client and the web server Though other classes exist within the name, the one we are going to look at is the WebRequestclass
The Sys.Net.WebRequestclass provides support for making HTTP requests The following sample code, for example, makes a web request
var request;
268
Trang 9function MakeCall() {
request = new Sys.Net.WebRequest();
var url = Sys.Net.WebRequest.createUrl(“PageThatIsCalled.aspx”, null);
request.set_url(url);
request.completed.add(RequestCompleted);
request.timeout.add(RequestTimeOut);
request.invoke();
} function RequestCompleted(objSender, evArgs) {
if (blRun == true ) {
var obj = objSender.get_webRequest();
var objWR = objSender.get_data();
debug.dump(objWR, “Web Content:”, true);
} } Figure 10-9 shows the output of the preceding code In this example, the content from the called page is contained within the debug.dumpstatement as expected In the preceding example, a call is made out to
a web page in the same directory, and its contents are displayed
Figure 10-9
Sys.Data.DataColumn
The Sys.Datanamespace provides a set of classes that are essentially client-side versions of the similar classes in the System.Datanamespace of the NET Framework This namespace provides support for classes called DataColumn, DataRow, DataTable, DataView, DataFilter, DataSource, and PropertyFilter
269
Trang 10The Sys.Data.DataColumnclass allows for the interrogation of column information within a
Sys.Data.DataTableclass The DataColumnexposes the following members These members will be useful for processing datasets and data tables that are returned from a web service
get_columnName() This method will retrieve the column name of a specific column get_dataType() This method will retrieve the datatype of the column
get_defaultValue() This method will retrieve the default value of a column
dispose() This method will dispose()of the object and perform any
nec-essary cleanup
The following example code will interrogate a returned dataset The first thing that is necessary is to get
a datatable This is performed by calling the result.getItem(0)method
function MethodReturn(result)
{
var i = 0;
var str = “”;
var strColInfo = “”;
var strReturn = “<br />”;
for (prop in result) str += “Property: “ + prop + “\r\n”;
alert(str);
var tbl1 = result.getItem(0);
for(i = 0; i < tbl1.get_columns().length; i++) {
strColInfo += tbl1.get_columns()[i].get_columnName() + “:” + tbl1.get_columns()[i].get_dataType() + strReturn;
} document.getElementById(“ColInfo”).innerHTML = strColInfo }
In the preceding code, a web service returns a dataset in the result variable to the MethodReturn() JavaScript function There is a for()loop that returns the properties/members of the result object This
is then presented to the user in an alert()box This alert()box is only for information’s sake The first table in the dataset is pulled out of the dataset by calling result.getItem(0) Within the first table, the next for()loop iterates through the columns returned, gets the datatype, and creates a string, and after the for()loop exits, the data is presented to the user
Figure 10-10 shows the output of the preceding code One thing to notice is that the get_dataType() returns information
270