
 |
|
XML Programming (Core Reference)
|
|
 |
Author |
 |
R. Allen Wyke, Sultan Rehman, Brad Leupen
|
 |
|
Pages |
736
|
|
Disk |
1 Companion CD(s)
|
|
Level |
Intermediate
|
|
Published |
01/09/2002
|
|
ISBN |
9780735611856
|
|
ISBN-10 |
0-7356-1185-8
|
|
Price(USD) |
$59.99
To see this book's discounted price, select a reseller below.
|
|
|
|
|
 |
|
|
Chapter 9: Building a Server Application continued
Business Objects
The Golf Reservation System server will contain class descriptions that model the database entities shown previously in an object format. Class definitions will exist for GolfCourse, Golfer, Tee, Hole, and TeeTime. A generic Address class will also be provided as a uniform means to represent golf course and golfer addresses. Instances or collections of instances of these objects will be returned by Web methods.
Golf Reservation System clients will need to download stub representations of these classes to make sense of the return results. Visual Studio .NET takes care of this by adding Web references. Other clients will need to query the WSDL document for the GolfCourseService XML Web service.
GolfCourse
The GolfCourse object provides an objectified view of objects in the course database table. The class definition for this object resides in GolfCourse.cs. The GolfCourse object is used primarily as a means to transport information back to an XML Web services client. The class uses public properties so that they can be included as a return result from an XML Web service call.
using System; using System.Data; namespace TeeTimes { /// <summary> /// A GolfCourse /// </summary> public class GolfCourse { public int id; public String name; public String description; public String price; public String telephone; public Address address; public Tee[] tees;
The GolfCourse object has four different constructors. The first is the default constructor, which initializes all its properties to null.
public GolfCourse() { id = 0; name = ""; description = ""; price = ""; telephone = ""; address = new Address(); tees = null; }
The second constructor takes a row in a typed data set as an argument. The course's properties are initialized by the properties contained in the data row.
public GolfCourse(courseDataSet.courseRow c) { name = ""; description = ""; price = ""; address = new Address(); tees = null; id = c.id; if (!c.IsnameNull()) name = c.name; if (!c.IsdescriptionNull()) description = c.description; if (!c.IspriceNull()) price = c.price; if (!c.IstelephoneNull()) telephone = c.telephone; if (!c.IsstreetAddressNull()) address.street = c.streetAddress; if (!c.IscityNull()) address.city = c.city; if (!c.IsstateNull()) address.state = c.state; if (!c.IspostalCodeNull()) address.postalCode = c.postalCode; if (!c.IscountryNull()) address.country = c.country; }
The third constructor accepts a DataRowView object that was obtained via a DataView filter. The DataRowView is untyped, so the constructor must use array access to load its properties.
public GolfCourse(DataRowView c) { id = 0; name = ""; description = ""; price = ""; address = new Address(); tees = null; id = Int32.Parse(c["id"].ToString()); name = c["name"].ToString(); description = c["description"].ToString(); price = c["price"].ToString(); telephone = c["telephone"].ToString(); address.street = c["streetAddress"].ToString(); address.city = c["city"].ToString(); address.state = c["state"].ToString(); address.postalCode = c["postalCode"].ToString(); address.country = c["country"].ToString(); }
The fourth and final GolfCourse constructor accepts a reference to a typed DataSet object and a primary key value. The constructor calls the DataSet object's FindById() method to obtain the correct row. If the row exists the constructor uses the data contained therein to initialize the GolfCourse object.
public GolfCourse(courseDataSet ds, int courseId) { id = 0; name = ""; description = ""; price = ""; address = new Address(); courseDataSet.courseRow c = ds.course.FindByid(courseId); if (c != null) { id = courseId; name = ""; description = ""; price = ""; address = new Address(); if (!c.IsnameNull()) name = c.name; if (!c.IsdescriptionNull()) description = c.description; if (!c.IspriceNull()) price = c.price; if (!c.IstelephoneNull()) telephone = c.telephone; if (!c.IsstreetAddressNull()) address.street = c.streetAddress; if (!c.IscityNull()) address.city = c.city; if (!c.IsstateNull()) address.state = c.state; if (!c.IspostalCodeNull()) address.postalCode = c.postalCode; if (!c.IscountryNull()) address.country = c.country;
The GolfCourse contructor locates all the course's Tee objects, instantiates them, and initializes the tees array property in the following:
DataView teeView = new DataView(ds.tee); int teeCnt = ds.tee.Count; teeView.RowFilter = "courseId = "+courseId; int cnt = 0; tees = new Tee[teeView.Count]; foreach (DataRowView r in teeView) { int tee_id = Int32.Parse(r["id"].ToString()); Tee tee = new Tee(ds,tee_id); tees[cnt] = tee; cnt++; } } }
Public getters and setters are used to manipulate the GolfCourse's properties.
public int getId() { return id; } public String getName() { return name; } public String getDescription() { return description; } public Address getAddress() { return address; } public String getPrice() { return price; } public String getTelephone() { return telephone; } public void setId(int _id) { id = _id; } public void setName(String _name) { name = _name; } public void setDescription(String _description) { description = _description;} public void setPrice(String _price) { price = _price; } public void setTelephone(String _telephone) { telephone = _telephone; }
The class provides a setAddress() method to update the Address-dependent object.
public void setAddress(String street, String city, String state, String postalCode, String country) { address.setStreet(street); address.setCity(city); address.setState(state); address.setPostalCode(postalCode); address.setCountry(country); } } }
Golfer
The Golfer object maintains all golfer and user states. Golfer object references can also be included within Web method result documents. The class definition for this object is shown in Golfer.cs.
using System; namespace TeeTimes { /// <summary> /// Summary description for Golfer. /// </summary> public class Golfer { public int id; public String firstName; public String lastName; public String email; public String phone; public String username; public String password; public Address address;
The Golfer object also has several constructors.
public Golfer() { id = 0; firstName = ""; lastName = ""; email = ""; phone = ""; username = ""; password = ""; address = new Address(); }
This constructor accepts a list of all Golfer properties to be initialized.
public Golfer(String _firstName, String _lastName, String _email, String _phone, String _streetAddress, String _city, String _state, String _postalCode, String _country, String _username, String _password) { firstName = _firstName; lastName = _lastName; email = _email; phone = _phone; username = _username; password = _password; address = new Address(); address.setStreet(_streetAddress); address.setCity(_city); address.setState(_state); address.setPostalCode(_postalCode); address.setCountry(_country); }
This constructor accepts the typed courseDataSet object and a Golfer id value. The constructor looks up the Golfer in the data set and sets its properties accordingly.
public Golfer(courseDataSet ds, int golferId) { id = 0; firstName = ""; lastName = ""; email = ""; phone = ""; username = ""; password = ""; address = new Address(); courseDataSet.golfersRow g = ds.golfers.FindByid(golferId); if (g != null) { id = golferId; if (!g.IsfirstNameNull()) firstName = g.firstName; if (!g.IslastNameNull()) lastName = g.lastName; if (!g.IsemailNull()) email = g.email; if (!g.IsphoneNull()) phone = g.phone; if (!g.IsusernameNull()) username = g.username; if (!g.IspasswordNull()) password = g.password; if (!g.IsstreetAddressNull()) address.setStreet(g.streetAddress); if (!g.IscityNull()) address.setCity(g.city); if (!g.IsstateNull()) address.setState(g.state); if (!g.IspostalCodeNull()) address.setPostalCode(g.postalCode); if (!g.IscountryNull()) address.setCountry(g.country); } }
The following are the Golfer accessor and mutator methods:
public int getId() { return id; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public String getEmail() { return email; } public String getPhone() { return phone; } public String getUserName() { return username; } public String getPassword() { return password; } public Address getAddress() { return address; } public void setId(int _id) { id = _id; } public void setFirstName(String _firstName) { firstName = _firstName; } public void setLastName(String _lastName) { lastName = _lastName; } public void setEmail(String _email) { email = _email; } public void setPhone(String _phone) { phone = _phone; } public void setUserName(String _username) { username = _username; } public void setPassword(String _password) { password = _password; } public void setAddress(String streetAddress, String city, String state, String postalCode, String country) { address.setStreet(streetAddress); address.setCity(city); address.setState(state); address.setPostalCode(postalCode); address.setCountry(country); } } }
Tee
The Tee class models the different types of tees that a golf course might have, such as red, white, and blue. Each Tee has its own set of yardage, slope, and distance properties as well as a collection of 18 unique Hole objects. Tee.cs contains the class definition.
using System; using System.Data; namespace TeeTimes { /// <summary> /// Summary description for Tee. /// </summary> public class Tee { public int id; public double slope; public int distance; public String description; public int courseId; public Hole[] holes; public Tee() { } public Tee(int _id, int _courseId, String _description, float _slope) { id = _id; courseId = _courseId; description = _description; slope = _slope; holes = null; }
Again, we see the Data Set/ID constructor design pattern. You have the option to decide how "data-aware" your business objects should be. We overloaded our business objects' constructors to perform the most data-set access. Doing so simplifies the XML Web service logic.
public Tee(courseDataSet ds, int teeId) { courseDataSet.teeRow t = ds.tee.FindByid(teeId); if (t != null) { id = teeId; courseId = t.courseId; description = t.description; slope = t.slope;
Here the Tee constructor builds an array of dependent Hole objects. We use a DataView object to filter the courseDataSet and generate a list of keys. We iterate over these keys, construct the objects, and create our holes array.
DataView holeView = new DataView(ds.Hole); holeView.RowFilter = "teeId = "+teeId; holeView.Sort = "hole"; int cnt = 0; holes = new Hole[holeView.Count]; foreach (DataRowView r in holeView) { Hole hole = new Hole(); hole.setTeeId(teeId); int hole_handicap = Int32.Parse(r["handicap"].ToString()); int hole_length = Int32.Parse(r["length"].ToString()); int hole_hole = Int32.Parse(r["hole"].ToString()); int hole_par = Int32.Parse(r["par"].ToString()); hole.setHandicap(hole_handicap); hole.setLength(hole_length); hole.setHole(hole_hole); hole.setPar(hole_par); holes[cnt] = hole; cnt++; } } }
These are the Tee accessors and mutators.
public int getId() { return id; } public double getSlope() { return slope; } public int getDistance() { return distance; } public int getCourseId() { return courseId; } public String getDescription() { return description; } public Hole[] getHoles() { return holes; } public void setId(int _id) { id = _id; } public void setSlope(double _slope) { slope = _slope; } public void setDistance(int _distance) { distance = _distance; } public void setCourseId(int _courseId) { courseId = _courseId; } public void setDescription(String _description) { description = _description; } public void setHoles(Hole[] _holes) { holes = _holes; } } }
Hole
Contrary to common sense, a single golf course might have 18, 36, 54, or more holes because each hole is different with respect to the tee from which the golfer is playing on a given day. A hole that plays 320 yards from the white tees might play 380 yards from the blue tees. To accommodate this requirement we decided to give each tee its own collection of 18 hole objects. The Hole class definition is found in Hole.cs.
using System; namespace TeeTimes { /// <summary> /// Summary description for Hole Class /// </summary> public class Hole { public int id; public int teeId; public int handicap; public int length; public int hole; public int par; public Hole() { id = 0; teeId = 0; handicap = 0; length = 0; hole = 0; par = 0; }
Hole constructors are always fed properties by value in the server project. This class might be extended later to provide the DataSet/ID constructor interface.
public Hole(int _id, int _teeId, int _handicap, int _length, int _hole, int _par) { id = _id; teeId = _teeId; handicap = _handicap; length = _length; hole = _hole; par = _par; } public int getId() { return id; } public int getTeeId() { return teeId; } public int getHandicap() { return handicap; } public int getLength() { return length; } public int getHole() { return hole; } public int getPar() { return par; } public void setId(int _id) { id = _id; } public void setTeeId(int _teeId) { teeId = _teeId; } public void setHandicap(int _handicap) { handicap = _handicap; } public void setLength (int _length) { length = _length; } public void setHole (int _hole) { hole = _hole; } public void setPar (int _par) { par = _par; } } }
TeeTime
The TeeTime class represents a tee-time booking on a specific date and time. TeeTime objects hold references to a golfer and a golf course. TeeTime objects can be obtained by XML Web services clients for a specific golf course to see what times are still available for play. TeeTime.cs shows the source code behind the TeeTime class.
using System; namespace TeeTimes { /// <summary> /// Summary description for TeeTime. /// </summary> public class TeeTime { public int id; public DateTime date; public DateTime time; public int courseId; public int golfer; public TeeTime() { id = 0; date = System.DateTime.Now; time = System.DateTime.Now; courseId = 0; golfer = 0; } public TeeTime(int _id, DateTime _date, DateTime _time, int _courseId, int _golfer) { id = _id; date = _date; time = _time; courseId = _courseId; golfer = _golfer; }
Again, we see the Data Set/ID constructor pattern.
public TeeTime(courseDataSet ds, int ttId) { id = 0; date = System.DateTime.Now; time = System.DateTime.Now; courseId = 0; golfer = 0; courseDataSet.bookingsRow tt = ds.bookings.FindByid(ttId); if (tt != null) { id = ttId; if (!tt.IscourseIdNull()) courseId = tt.courseId; if (!tt.IsgolferNull()) golfer = tt.golfer; if (!tt.IsteeDateNull()) date = DateTime.Parse(tt.teeDate); if (!tt.IsteeTimeNull()) time = DateTime.Parse(tt.teeTime); } } public int getId() { return id; } public DateTime getDate() { return date; } public DateTime getTime() { return time; } public int getCourseId() { return courseId; } public int getGolfer() { return golfer; } public void setId(int _id) { id = _id; } public void setDate(DateTime _date) { date = _date; } public void setTime(DateTime _time) { time = _time; } public void setCourseId(int _courseId) { courseId = _courseId; } public void setGolfer(int _golfer) { golfer = _golfer; } } }
Address
The Address object is used to provide a common address API for the server. GolfCourses and Golfers both hold references to objects of this type. This class could be extended later to support multiple address, driving directions, and other functionalities. The class definition can be found in Listing .
Address.cs: The Address utility class.
using System; namespace TeeTimes { /// <summary> /// Summary description for Address. /// </summary> public class Address { public String street; public String city; public String state; public String postalCode; public String country; public Address() { street = ""; city = ""; state = ""; postalCode = ""; country = ""; } public String getStreet() { return street; } public String getCity() { return city; } public String getState() { return state; } public String getPostalCode() { return postalCode; } public String getCountry() { return country; } public void setStreet(String _street){ street = _street; } public void setCity(String _city){ city = _city; } public void setState(String _state){ state = _state; } public void setPostalCode(String __postalCode){ postalCode = _postalCode; } public void setCountry(String _country){ country = _country; } } }
The GolfCourseService XML Web service
All Golf Reservation System Web methods will be assembled into a single XML Web service called GolfCourseService. The application publishes relatively few methods, so only a single XML Web service umbrella is required. All access to the server's business logic will pass through this API.
You will notice that most of the Web methods are small. .NET takes care of all the complex SOAP argument marshaling and our business object handles most of the data access and all of the nested object creation. The Web methods don't need to do too much at all.
FindAll()
Syntax: GolfCourse[] FindAll()
FindAll() returns an array of GolfCourse objects. This method is called to get a complete listing of the courses maintained by the system. The method simply iterates over the entire course table in the GolfCourse data set.
[WebMethod] public GolfCourse[] FindAll() { int nCourses = courseDataSet1.course.Count; GolfCourse[] golfCourses = new GolfCourse[nCourses]; int cnt = 0; foreach (courseDataSet.courseRow c in courseDataSet1.course) { GolfCourse gc = new GolfCourse(c); golfCourses[cnt] = gc; cnt++; } return golfCourses; }
FindGeneric()
Syntax: GolfCourse[] FindGeneric(String[] fields, String[] values)
FindGeneric() implements a simple yet flexible query interface into the course database. Clients can pass in arrays of property names and value expressions (including * wildcards) that can be used to generate a list of matching courses. The method makes use of the .NET DataView class to filter data in the courseDataSet1 data set.
An added bonus of this design is that this method will not need to change as fields are added to the course table and dataset.
[WebMethod] public GolfCourse[] FindGeneric(String[] fields, String[] values) { DataView cv = new DataView(courseDataSet1.course); cv.Sort = "name"; String filterString = ""; for (int x = 0; x < fields.Length; x++) { if (x >= 1) { filterString += " AND"; } filterString += " "+fields[x]+" LIKE '"+values[x]+"'"; } cv.RowFilter = filterString; int nCourses = cv.Count; GolfCourse[] golfCourses = new GolfCourse[nCourses]; int cnt = 0; foreach (DataRowView c in cv) { int gcId = Int32.Parse(c["id"].ToString()); GolfCourse gc = new GolfCourse(courseDataSet1, gcId); golfCourses[cnt] = gc; cnt++; } return golfCourses; }
GetCourseDetail()
Syntax: GolfCourse GetCourseDetail(String id)
GetCourseDetail() returns a complete representation of a golf course. Tees and Holes are returned as nested arrays. This method is a good example of a coarse- grained Web method. Recall that the GolfCourse constructor that is called here recursively builds arrays of Tees and Holes. A single call to this method retrieves enough information to be displayed on three different Web forms.
[WebMethod] public GolfCourse GetCourseDetail(String id) { int cid = Int32.Parse(id); GolfCourse gc = new GolfCourse(courseDataSet1,cid); return gc; }
AddCourse()
Syntax: GolfCourse AddCourse(String name, String description, String price, String streetAddress, String city, String state, String postalCode, String country, String telephone)
AddCourse() creates a new course entry in the golf course database.
[WebMethod] public GolfCourse AddCourse(String name, String description, String price, String streetAddress, String city, String state, String postalCode, String country, String telephone) { courseDataSet.courseRow newCourse = courseDataSet1.course. AddcourseRow(city,country,description,name, postalCode,price,state,streetAddress,telephone); courseDataAdapter.Update(courseDataSet1,"course"); courseDataSet1.AcceptChanges(); GolfCourse gc = new GolfCourse(newCourse); return gc; }
AddTee()
Syntax: GolfCourse AddTee(int courseId, String description, float slope
AddTee() creates a new tee entry for a particular golf course.
[WebMethod] public GolfCourse AddTee(int courseId, String description, float slope) { courseDataSet.teeRow newTee = courseDataSet1.tee.AddteeRow(courseId,description,0,slope); teeDataAdapter.Update(courseDataSet1,"tee"); courseDataSet1.AcceptChanges(); GolfCourse gc = new GolfCourse(courseDataSet1, courseId); return gc; }
AddHole()
Syntax: GolfCourse AddHole(int teeId, int handicap, int length, int hole, int par)
AddHole() adds a new hole record to the Hole database. The hole must be associated with a particular Tee object.
[WebMethod] public GolfCourse AddHole(int teeId, int handicap, int length, int hole, int par) { courseDataSet.HoleRow newHole = courseDataSet1.Hole.AddHoleRow (handicap,length,teeId,hole,par); holeDataAdapter.Update(courseDataSet1,"Hole"); courseDataSet1.AcceptChanges(); courseDataSet.teeRow tr = courseDataSet1.tee.FindByid(teeId); int courseId = tr.courseId; GolfCourse gc = new GolfCourse(courseDataSet1, courseId); return gc; }
AddTeeTime()
Syntax: TeeTime AddTeeTime(int courseId, int golfer, DateTime date, DateTime time)
AddTeeTime() creates a new tee time record. The tee time record requires valid references to a golf course and a golfer record. The method also takes in two DateTime objects, one representing the date of the tee time and the other representing the time.
[WebMethod] public TeeTime AddTeeTime(int courseId, int golfer, DateTime date, DateTime time) { String dateString = date.ToShortDateString(); courseDataSet.bookingsRow newBooking = courseDataSet1. bookings.AddbookingsRow(courseId,golfer,dateString,time.ToString()); bookingsDataAdapter.Update(courseDataSet1,"bookings"); courseDataSet1.AcceptChanges(); TeeTime tt = new TeeTime(0, date, time, courseId, golfer); return tt; }
FindTeeTimesByGolfer()
Syntax: TeeTime[] FindTeeTimesByGolfer(int golferId)
FindTeeTimesByGolfer() returns an array representing a complete tee time listing for a particular golfer. This listing can be used to remind a golfer of upcoming tee times. Again, we see the DataView object put to good use.
[WebMethod] public TeeTime[] FindTeeTimesByGolfer(int golferId) { DataView ttv = new DataView(courseDataSet1.bookings); ttv.Sort = "teeTime"; ttv.RowFilter = "golfer = '"+golferId+"'"; int nTimes = ttv.Count; TeeTime[] teeTimes = new TeeTime[nTimes]; int cnt = 0; foreach (DataRowView c in ttv) { int ttId = Int32.Parse(c["id"].ToString()); TeeTime tt = new TeeTime(courseDataSet1, ttId); teeTimes[cnt] = tt; cnt++; } return teeTimes; }
AddGolfer()
Syntax: Golfer AddGolfer(String firstName, String lastName, String streetAddress, String city, String state, String postalCode, String country, String email, String phone, String username, String password)
AddGolfer() creates a new golfer record in the database. This method requires all pertinent address and profile information.
[WebMethod] public Golfer AddGolfer(String firstName, String lastName, String streetAddress, String city, String state, String postalCode, String country, String email, String phone, String username, String password) { courseDataSet.golfersRow newGolfer = courseDataSet1.golfers. AddgolfersRow(city,country,email,firstName,lastName,phone, postalCode,state,streetAddress,password,username); golferDataAdapter.Update(courseDataSet1,"golfers"); courseDataSet1.AcceptChanges(); Golfer g = new Golfer(firstName,lastName,email,phone, streetAddress,city,state,postalCode,country,username,password); return g; }
FindGolferById()
Syntax: Golfer FindGolferById(int golferId)
FindGolferById() looks up a specific golfer and returns a Golfer object with matching ID if one exists. It doesn't get any easier than this.
[WebMethod] public Golfer FindGolferById(int golferId) { return new Golfer(courseDataSet1,golferId); }
ValidateLogin()
Syntax: Golfer ValidateLogin(String username, String password)
ValidateLogin() is used to validate username/password combinations against the Golfer database. This is necessary to prevent fake tee times from being created. If the validation succeeds, the method returns the entire Golfer object. If it fails, the method returns null.
[WebMethod] public Golfer ValidateLogin(String username, String password) { DataView gv = new DataView(courseDataSet1.golfers); gv.RowFilter = "username = '"+username+"' AND password = '"+password+"'"; int gCount = gv.Count; Golfer g = null; if (gCount >= 1) { DataRowView gr = gv[0]; int golferId = Int32.Parse(gr["id"].ToString()); g = new Golfer(courseDataSet1,golferId); } return g; }
FindTeeTimesByDate()
Syntax: TeeTime[] FindTeeTimesByDate(int courseId, DateTime date)
FindTeeTimesByDate() returns an array of tee times for a specified course on a specified date.
[WebMethod] public TeeTime[] FindTeeTimesByDate(int courseId, DateTime date) { DataView ttv = new DataView(courseDataSet1.bookings); ttv.Sort = "teeTime"; ttv.RowFilter = "teeDate = '"+date.ToShortDateString()+"' AND courseId = '"+courseId+"'"; int nTimes = ttv.Count; TeeTime[] teeTimes = new TeeTime[nTimes]; int cnt = 0; foreach (DataRowView c in ttv) { int ttId = Int32.Parse(c["id"].ToString()); TeeTime tt = new TeeTime(courseDataSet1, ttId); teeTimes[cnt] = tt; cnt++; } return teeTimes; }
FindTeeTimesByDateRange()
Syntax: TeeTime[] FindTeeTimesByDateRange(int courseId, DateTime startDate, DateTime endDate)
FindTeeTimesByDateRange() returns an array of tee times for a specified course across a specified date range. Because of a strange problem in one of the earlier .NET Studio releases, we were unable to write Access records with fields of type DateTime. Thus, we were forced to serialize dates and times to strings before writing them out. This made the process of filtering by date range significantly more difficult.
[WebMethod] public TeeTime[] FindTeeTimesByDateRange(int courseId, DateTime startDate, DateTime endDate) { DataView ttv = new DataView(courseDataSet1.bookings); ttv.Sort = "teeTime"; String filterText = "courseId = '"+courseId+"' AND ("; TimeSpan duration = endDate.Subtract(startDate); int nDays = duration.Days; for (int i = 0; i <= nDays; i++) { if (i > 0) filterText = filterText + " OR"; DateTime tDate = startDate.AddDays(i); filterText = filterText+" teeDate = '"+ tDate.ToShortDateString()+"'"; } filterText = filterText + ")"; ttv.RowFilter = filterText; int nTimes = ttv.Count; TeeTime[] teeTimes = new TeeTime[nTimes]; int cnt = 0; foreach (DataRowView c in ttv) { int ttId = Int32.Parse(c["id"].ToString()); TeeTime tt = new TeeTime(courseDataSet1, ttId); teeTimes[cnt] = tt; cnt++; } return teeTimes; }
Conclusion
In this chapter we've seen how to use XML and the .NET Developer Studio to create the server side of an enterprise application. We have used XML Web services, Web methods, data adapters, data classes, data views, and data connection utilities to make this happen. We are able to achieve a great deal of flexibility in our business logic by using XML Web services to erect an elegent partition around it. Our XML Web services can easily be called from a wide variety of clients, be it Web browsers, cell phones, thick client applications, or even other Web Services.
In Chapter 10 we will create a Web client that actually makes use of all this! Later, in Chapter 13, we will connect a wireless device to the same XML Web services.
Previous
| Table of Contents
| Next
Last Updated: December 12, 2001
|