In this section, we describe how to develop a web service, first from the point of view of service providers and then of the consumers.
Web Services providers implement web services and advertise them so that the clients can discover and make use of the services. Because web services run on top of HTTP, there must be a web server application of some sort on the machine that hosts the web services. This web server application can be Microsoft Internet Information Services (IIS), Apache, or any other program that can understand and process the HTTP protocol. In our examples, we use Microsoft IIS, since that is the only web server currently supported by .NET.
We will be building a web service called PubsWS to let consumers get information from the sample Pubs database. All data access will be done through ADO.NET, so make sure you’ve read Chapter 5 before attempting the examples.
Creating a web service is a three-step process.
Create a new asmx file for the web service. This
must contain the <%
webservice
...
%>
directive, as well as the class that
provides the web service implementation. To the Web Service clients,
this asmx file is the entry point to your Web
Service. You need to put this in a virtual directory that has the
executescripts permission turned on.
Inherit from the WebService class of the System.Web.Services
namespace. This allows the derived class to access all the normal ASP
objects exposed in the WebService base class. From this point, you
can use these ASP objects as if you were developing an ASP-based
application.[39] It is highly recommended that you specify a
namespace for your web service before publishing it publicly because
the default namespace, http://tempuri.org/, will not uniquely
identify your web service from other web services. To do this, all
you have to do is to tag the web service class with the
Namespace
attribute, specifying your own
namespace.
Tag the public methods with WebMethod attributes to make web methods—public methods of a distributed component that are accessible via the Web. You don’t have to tag a method as WebMethod unless you want that method to be published as a web method.
The following C# code
demonstrates a simple web service that exposes four methods to
Internet clients. We emphasize
“Internet” because anyone that can access this
asmx
file on the web server can access these
methods, as opposed to your COM component, which can be accessed only
by COM clients:
<%@ WebService Language="C#" Class="PubsWS.PubsWS" %>
namespace PubsWS { using System; using System.Data; using System.Data.OleDb; using System.Web; using System.Web.Services; [WebService(Namespace="http://Oreilly/DotNetEssentials/")] public class PubsWS : WebService { private static string m_sConnStr = "provider=sqloledb;server=(local);database=pubs;uid=sa;pwd=;";[WebMethod(Description="Returns a DataSet containing all authors.")]
public DataSet GetAuthors( ) { OleDbDataAdapter oDBAdapter; DataSet oDS; oDBAdapter = new OleDbDataAdapter("select * from authors", m_sConnStr); oDS = new DataSet( ); oDBAdapter.Fill(oDS, "Authors"); return oDS; }[WebMethod]
public DataSet GetAuthor(string sSSN) { OleDbDataAdapter oDBAdapter; DataSet oDS; oDBAdapter = new OleDbDataAdapter( "select * from authors where au_id ='" + sSSN + "'", m_sConnStr); oDS = new DataSet( ); oDBAdapter.Fill(oDS, "SelectedAuthor"); return oDS; }[WebMethod(MessageName="GetBooksByAuthor",
Description="Find books by author's SSN.")]
public DataSet GetBooks(string sAuthorSSN) { OleDbDataAdapter oDBAdapter; DataSet oDS; oDBAdapter = new OleDbDataAdapter( "select * from titles inner join titleauthor on " + "titles.title_id=titleauthor.title_id " + "where au_id='" + sAuthorSSN + "'", m_sConnStr); oDS = new DataSet( ); oDBAdapter.Fill(oDS, "Books"); oDBAdapter = new OleDbDataAdapter("select * from authors " + "where au_id='" + sAuthorSSN + "'", m_sConnStr); oDBAdapter.Fill(oDS, "Author"); return oDS; }[WebMethod]
public DataSet GetBooks( ) { OleDbDataAdapter oDBAdapter; DataSet oDS; oDBAdapter = new OleDbDataAdapter("select * from titles" , m_sConnStr); oDS = new DataSet( ); oDBAdapter.Fill(oDS, "Books"); return oDS; } } // end PubsWS }
If you are familiar with ASP, you may recognize the usage of the @
symbol in front of keyword WebService
. This
WebService directive specifies the language of the web service so
that ASP.NET can compile the web service with the correct compiler.
This directive also specifies the class that implements the web
service so it can load the correct class and employ reflection to
generate the WSDL for the web service.
Because PubsWS also uses ADO.NET’s OLE DB provider for its data-access needs, we have to add a reference to System.Data and System.Data.OleDb, in addition to the System, System.Web, and System.Web.Services namespaces.
Class PubsWS inherits from WebService with the colon syntax that should be familiar to C++ or C# developers:
public class PubsWS : WebService
The four methods that are tagged with WebMethod attributes are
GetAuthors( ), GetAuthor( ),
GetBooks( string), and GetBooks( ). In C#, you
can tag public methods with a WebMethod attribute using the
[]
syntax. In VB, you must use <>
. For example, in VB, the second method would be
declared as:
Public Function <WebMethod( )> GetAuthor(sSSN As String) As DataSet
By adding [WebMethod]
in front of your public
method, you make the public method callable from any Internet client.
What goes on behind the scenes is that your public method is
associated with an attribute, which is
implemented as a WebMethodAttribute class. WebMethodAttribute has six
properties:
Specifies the length of time, in seconds, to keep the method response in cache. The default is not to hold the method response in cache (0 seconds).
Provides additional information about a particular web method.
Enables or disables session state. If you don’t intend to use
session state for the web method, you might want to disable this flag
so that the web server does not have to generate and manage session
IDs for each user accessing this web method. This might improve
performance. This flag is true
by default.
Distinguishes web methods with the same names. For example, if you
have two different methods called GetBooks (one method retrieves all
books while the other method retrieves only books written by a
certain author) and you want to publish both of these methods as web
methods, the system will have a problem trying to distinguish the two
methods since their names are duplicated. You have to use the
MessageName property to make sure all service signatures within the
WSDL are unique. If the protocol is SOAP, MessageName is mapped to
the SOAPAction
request header and nested within
the soap:Body
element. For HTTP GET and HTTP POST,
it is the PathInfo portion of the URI (as in http://localhost//PubsWS/PubsWS.asmx/GetBooksByAuthor).
Can be one of five modes: Disabled, NotSupported, Supported, Required, and RequiresNew. Even though there are five modes, web methods can only participate as the root object in a transaction. This means both Required and RequiresNew result in a new transaction being created for the web method. The Disabled, NotSupported, and Supported settings result in no transaction being used for the web method. The TransactionOption property of a web method is set to Disabled by default.
To set up these properties, pass the property name and its value as a
name
=
value
pair:
[WebMethod(Description="Returns a DataSet containing all authors.")] public DataSet GetAuthors( )
You can separate multiple properties with a comma:
[WebMethod(MessageName="GetBooksByAuthor", Description="Find books by author's SSN.")] public DataSet GetBooks(string sAuthorSSN)
If you set up your web services from scratch, you might also need to
provide the configuration file (web.config
) in
the same directory as your asmx
file. This
configuration file allows you to control various application settings
about the virtual directory. The only thing we recommend definitively
is to set the authentication mode to None
to make
our web services development and testing a little easier. When you
release your web services to the public, you would probably change
this setting to Windows
, Forms
,
or Passport
instead of None
:
<configuration> <system.web> <authentication mode="None" /> </system.web> </configuration>
The following list shows the different modes of authentication:
Basic Forms authentication is where unauthenticated requests are redirected to a login form.
Authentication is performed by IIS in one of three ways: basic, digest, or Integrated Windows Authentication.
Unauthenticated requests to the resource are redirected to Microsoft’s centralized authentication service. When authenticated, a token is passed back and used by subsequent requests.
[39] You will have to get to the Request and Response objects through the Context property of the WebService class.
18.217.150.88