To ease development, I recommend
using the Visual Studio.NET IDE. However, you are free to develop your
application in the favorite editor of your choice, using the command-line to
execute the various commands to build and deploy it.
Building Web Service components using the
.NET Framework
Web Services run on top of HTTP.
Therefore, they are developed and deployed on a Web Server and their URL is
advertised so that "Internet" clients can discover and make use of their
services. Even though that Web Server can be Microsoft IIS, or Apache, or any
other such server, at this point in time, the .NET framework only supports
deployment on Microsoft IIS.
In this article, we will build a
web service called OIDServer
that clients can use to generate a unique Object Identity (OID) string. The
generated OID string is unique, and can be used by the client wherever unique
keys are needed - either for COM GUIDs, or to act as a unique primary key for a
database table, etc. Since the Web Service class is deployed on a Web Server,
any "Internet" client can access it and make use of its services - as
opposed to COM components which can only be accessed by COM clients.
The various steps that are
involved in creating a Web Service Component using C# and the .NET Framework are as follows
(I'm going to assume you're using the VS.NET IDE):
Create a Visual C# - ASP.NET Web
Service
project
Develop the
OIDServer.asmx
file and the
OIDServer.asmx.cs
class file
Modify the generated
AssemblyInfo.cs
to add the right assembly information
Build the Project Files
1. Create a Visual C# - ASP.NET Web
Service project
Create a new Visual C# ASP.NET Web
Service project.
2. Develop the
OIDServer.asmx
file and the
OIDServer.asmx.cs
class file
Visual Studio.NET creates a bunch of files for
you to use while developing your web service. Of particular interest for our
discussion now are, the
OIDServer.asmx
file and the
OIDServer.asmx.cs
class file.
The
OIDServer.asmx file
OIDServer.asmx
contains the
<%@
WebService... %>
directive, as well as the class that provides the implementation in the
Class="OIDServer.OIDServer"
directive. To any web service client,
the .asmx
file serves as the main entry point to the Web Service. This file needs to be
hosted on a virtual directory on IIS that has the
executescripts
permission turned on.
People familiar with ASP will immediately
recognize the @
symbol in front of the WebService
keyword. The WebService directive specifies the language used to develop the web
service so that ASP.NET can compile this service with the right compiler. The
Class="OIDServer.OIDServer"
directive specifies the class that implements the web service, so that the right
class can be loaded and its Web Services Description (WSDL) generated using
reflection.
The
OIDServer.asmx.cs
Class file
As shown on Line 34, Web Services derive from
the System.Web.Services.WebService
class
which allows the web service object to access all normal ASP objects exposed in
the
WebService
base class. This means, the
OIDServer
class can use ASP objects as though it were a regular ASP based application. As
the default namespace http://tempuri.org/ will
not uniquely identify our web service from other web services on the internet,
we specify our own namespace http://icommware.com
before publishing our web service publicly as shown on Line 32. The
Namespace =
"http://icommware.com"
attribute facilitates us to specify our own
namespace. Unless you don't want to publish a method, you need to tag all public
methods with the WebMethod
attribute to make web methods public methods of a distributed component that are
accessible though the world-wide web. This is shown on line 64.
////////////////////////////////////////////////////// /// The following example illustrates a Web Service /// developed using C# and the .NET Framework. /// /// author:
Gopalan Suresh Raj /// Copyright (c), 2002. All Rights Reserved. /// URL:
https://gsraj.tripod.com/ /// email:
gopalan@gmx.net /// /// <generate> /// wsdl /l:CS /protocol:SOAP http://localhost/OIDServer/OIDServer.asmx?WSDL /// wsdl /l:CS /protocol:HttpGet http://localhost/OIDServer/OIDServer.asmx?WSDL /// wsdl /l:CS /protocol:HttpPost http://localhost/OIDServer/OIDServer.asmx?WSDL /// </generate> /// <compile> /// csc /t:library /r:System.Web.Services.dll /r:System.Xml.dll OIDServer.dll /// </compile> ////////////////////////////////////////////////////// using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Web; using System.Web.Services; using System.EnterpriseServices;
namespace OIDServer { /// <summary> /// Summary description for OIDServer. /// </summary> [WebService ( Namespace =
"http://icommware.com", Name =
"OIDServer", Description =
"Generates unique Object Identity (OID)" )] public class OIDServer :
System.Web.Services.WebService {
/// <summary> /// Default No argument constructor /// </summary> public OIDServer() { //CODEGEN: This call is required by the ASP.NET Web Services Designer InitializeComponent(); }
#region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { } #endregion
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { }
/// <summary> /// Generates unique Object Identity (OID). Returns a String representation /// of the value of a new GUID in the Windows Registry format. /// </summary> /// <returns></returns> [WebMethod( EnableSession =
true, TransactionOption = TransactionOption.Disabled, BufferResponse =
false, CacheDuration = 0, MessageName =
"generateOID", Description =
"Generates unique Object Identity (OID)" )] public string generateOID () { return Guid.NewGuid ().ToString(); } } }
Notice that the
generateOID()
method on Line 64 is tagged with the
WebMethod tag using the
[]
syntax. By specifying the [WebMethod]
tag in front of this public method, we make
this public method callable from any Internet client. Behind the scenes, the
generateOID()
method is associated with an attribute which is implemented as a
WebMethodAttribute
class. This class has six properties which are also specified from Lines 64
through 66.
The
EnableSession property enables or disables
session state. If you don't intend to use session state for this web method, you
should disable this flag so that the web server does not generate and manage
session IDs for every user accessing this web method. This might improve
performance. This flag is true by default.
The
TransactionOption property can be one of
five values: Disabled,
NotSupported,
Supported,
Required,
and RequiresNew.
As Web Methods can participate only as the root object in a Transaction, both
Required
and RequiresNew
options result in a new transaction being created
for the Web Method. The Disabled,
NotSupported,
and Supported
options result in no transactions being used for the web methods. The
TransactionOption
property is set to Disabled
by default.
The
BufferResponse property controls whether or
not to buffer the method's response.
The
CacheDuration property specifies the length
of time, in seconds, to keep the method response in the cache. The default does
not hold the response in the cache (0 seconds).
The
MessageName property is used to distinguish
web methods with the same names. For example, if you have two methods with the
same name, and you want to publish both these methods as web methods, the system
will have a problem identifying one from the other as their names are
duplicated. This property ensures that all service signatures in the WSDL are
unique.
The
Description property provides additional
descriptive information about a particular method.
3.
Modify the generated
AssemblyInfo.cs
to add the right assembly information
You provide the compiler with your assembly
information in an assembly file called
AssemblyInfo.cs. The assembly information
file is compiled with the rest of the project's source files. The
information is in the form of assembly
attributes - directives to the compiler on the information to embed in the
assembly.
using System.Reflection; using System.Runtime.CompilerServices;
// // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly: AssemblyTitle("OID Server")] [assembly: AssemblyDescription("Creates unique Object Identity (OID)")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("eCommWare Corporation")] [assembly: AssemblyProduct("OID Server")] [assembly: AssemblyCopyright("(c) 2001, Gopalan Suresh Raj. All Rights Reserved.")] [assembly: AssemblyTrademark("Web Cornucopia")] [assembly: AssemblyCulture("en-US")]
// // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
// // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the "project output directory". The location of the project output // directory is dependent on whether you are working with a local or web project. // For local projects, the project output directory is defined as // <Project Directory>\obj\<Configuration>. For example, if your KeyFile is // located in the project directory, you would specify the AssemblyKeyFile // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // For web projects, the project output directory is defined as // %HOMEPATH%\VSWebCache\<Machine Name>\<Project Directory>\obj\<Configuration>. // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")]
The
OIDServer.vsdisco
file
Whenever a remote (or local) client is
interested in using a Web Service, the first step is to determine which web
services exist on a given machine. Even though the .NET class library provides
the API that allows you to examine registered Web Services programmatically,
discovery services are also required by numerous case tools. The
.vsdisco
file is used to describe each Web Service in a given virtual directory and any
related subfolders.
The generated
Web.config
file should normally be placed in the same directory as the
.asmx
file. This configuration file allows you to control various application settings
of the virtual directory. To ease development and testing, it is recommended
that you set the authentication mode
to None
as shown on Line 28. However, when releasing the web service to the public, you
can change it to either Windows,
or Forms,
or Passport,
as opposed to None.
The
authentication mode set to
Windows
indicates that authentication is performed by IIS in one of three ways - basic,
digest, or Integrated Windows Authentication.
The
authentication mode set to
Forms
indicates that un-authenticated requests are redirected to a login page.
The
authentication mode set to
Passport
indicates that un-authentication requests are directed to Microsoft's
centralized authentication service. When authenticated, a token is passed back
and used by subsequent requests.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <!-- DYNAMIC DEBUG COMPILATION Set compilation debug="true" to enable ASPX debugging. Otherwise, setting this value to false will improve runtime performance of this application. Set compilation debug="true" to insert debugging symbols (.pdb information) into the compiled page. Because this creates a larger file that executes more slowly, you should set this value to true only when debugging and to false at all other times. For more information, refer to the documentation about debugging ASP.NET files. --> <compilation defaultLanguage="c#" debug="true" /> <!-- CUSTOM ERROR MESSAGES Set mode="on" or "remoteonly" to enable custom error messages, "off" to disable. Add <error> tags for each of the errors you want to handle. --> <customErrors mode="Off" /> <!-- AUTHENTICATION This section sets the authentication policies of the application. Possible modes are "Windows", "Forms", "Passport" and "None" --> <authentication mode="None" /> <!-- APPLICATION-LEVEL TRACE LOGGING Application-level tracing enables trace log output for every page within an application. Set trace enabled="true" to enable application trace logging. If pageOutput="true", the trace information will be displayed at the bottom of each page. Otherwise, you can view the application trace log by browsing the "trace.axd" page from your web application root. --> <trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" /> <!-- SESSION STATE SETTINGS By default ASP.NET uses cookies to identify which requests belong to a particular session. If cookies are not available, a session can be tracked by adding a session identifier to the URL. To disable cookies, set sessionState cookieless="true". --> <sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;user id=sa;password=" cookieless="false" timeout="20" /> <!-- PREVENT SOURCE CODE DOWNLOAD This section sets the types of files that will not be downloaded. As well as entering a httphandler for a file type, you must also associate that file type with the aspnet_isapi.dll in the App Mappings property of the web site, or the file can be downloaded. It is recommended that you use this section to prevent your sources being downloaded. --> <httpHandlers> <add verb="*" path="*.vb" type="System.Web.HttpNotFoundHandler,System.Web" /> <add verb="*" path="*.cs" type="System.Web.HttpNotFoundHandler,System.Web" /> <add verb="*" path="*.vbproj" type="System.Web.HttpNotFoundHandler,System.Web" /> <add verb="*" path="*.csproj" type="System.Web.HttpNotFoundHandler,System.Web" /> <add verb="*" path="*.webinfo" type="System.Web.HttpNotFoundHandler,System.Web" /> </httpHandlers> <!-- GLOBALIZATION This section sets the globalization settings of the application. --> <globalization requestEncoding="utf-8" responseEncoding="utf-8" /> </system.web> </configuration>
4. Build the Project Files
Build the files that make up the project.
------
Rebuild All started: Project: OIDServer, Configuration: Debug .NET ------
Preparing resources...
Updating references...
Performing main compilation...
Build complete -- 0 errors, 0 warnings
Building satellite assemblies...
5. Deploy the Web Service files on IIS, and test
your Web Service
As soon as you compile your Web Service, you
can use it by executing it from the Visual Studio.NET IDE - Run or Debug the
Application. By default, the machine's active browser functions as a makeshift
client, that shows a HTML view of all the methods marked with the
[WebMethod]
attribute as shown in the figure below.
You can invoke the
generateOID()
method by clicking the generateOID
link and you'll get the following page shown.
When you click on the Invoke button, the web
service is invoked and the result is displayed on the next page.
Now you need to build a client application that
can access this Web Service component over the web.
Building a complete
Web Service component using C# and .NET