Showing posts with label webservice. Show all posts
Showing posts with label webservice. Show all posts

Thursday, 2 February 2012

Web Services Description Language Tool


The Web Services Description Language tool generates code for XML Web services and XML Web service clients from WSDL contract files, XSD schemas, and .discomap discovery documents.
wsdl [options] {URL | path}
ArgumentDescription
URL
The URL to a WSDL contract file (.wsdl), XSD schema file (.xsd), or discovery document (.disco). Note that you cannot specify a URL to a .discomap discovery document.
Path
The path to a local WSDL contract file (.wsdl), XSD schema file (.xsd), or discovery document (.disco or .discomap).
OptionDescription
/appsettingurlkey:key
or
/urlkey:key
Specifies the configuration key to use in order to read the default value for the URL property when generating code. When using the/parameters option, this value is the <appSettingUrlKey> element and contains a string.
/appsettingbaseurl:baseurl
or
/baseurl:baseurl
Specifies the base URL to use when calculating the URL fragment. The tool calculates the URL fragment by converting the relative URL from the baseurl argument to the URL in the WSDL document. You must specify the /appsettingurlkey option with this option. When using the /parameters option, this value is the <appSettingBaseUrl> element and contains a string.
/d[omain]:domain
Specifies the domain name to use when connecting to a server that requires authentication. When using the /parameters option, this value is the <domain> element and contains a string.
/l[anguage]:language
Specifies the language to use for the generated proxy class. You can specify CS (C#; default), VB (Visual Basic), JS (JScript) or VJS(Visual J#) as the language argument. You can also specify the fully qualified name of a class that implements theSystem.CodeDom.Compiler.CodeDomProvider Class. When using the /parameters option, this value is the <language> element and contains a string.
/n[amespace]:namespace
Specifies the namespace for the generated proxy or template. The default namespace is the global namespace. When using the /parameters option, this value is the <namespace> element and contains a string. This element must be in the parameters file.
/nologo
Suppresses the Microsoft startup banner display. When using the /parameters option, this value is the <nologo> element and contains either true or false.
/order
Generate explicit order identifiers on particle members.
/o[ut]:filename or directoryname
Specifies the file (or directory) in which to save the generated proxy code. You can also specify a directory in which to create this file. The tool derives the default file name from the XML Web service name. The tool saves generated datasets in different files. When using the /parameters option, this value is the <out> element and contains a string.
/parameters
Read command-line options from the specified xml file. Use this option to pass the Wsdl.exe tool a large number of options atone time. Short form is '/par:'. Option elements are contained inside a <wsdlParameters xmlns="http://microsoft.com/webReference/"> element. For details, see the Remarks section.
/parsableerrors
Displays errors in a format similar to the error reporting format used by language compilers. When using the /parameters option, this value is the <parsableerrors> element and is either true or false.
/p[assword]:password
Specifies the password to use when connecting to a server that requires authentication. When using the /parameters option, this value is the <password> element and contains a string.
/protocol:protocol
Specifies the protocol to implement. You can specify SOAP (default), HttpGetHttpPost, or a custom protocol specified in the configuration file. When using the /parameters option, this value is the <protocol> element and contains a string.
/proxy:URL
Specifies the URL of the proxy server to use for HTTP requests. The default is to use the system proxy setting. When using the /parameters option, this value is the <proxy> element and contains a string.
/proxydomain:domain
or
/pd:domain
Specifies the domain to use when connecting to a proxy server that requires authentication. When using the /parameters option, this value is the <proxydomain> element and contains a string.
/proxypassword:password
or
/pp:password
Specifies the password to use when connecting to a proxy server that requires authentication. When using the /parameters option, this value is the <proxypassword> element and contains a string.
/proxyusername:username
or
/pu:username
Specifies the user name to use when connecting to a proxy server that requires authentication. When using the /parameters option, this value is the <proxyusername> element and contains a string.
/server
Generates an abstract class for an XML Web service based on the contracts. The default is to generate client proxy classes. When using the /parameters option, this value is a <style> element that contains "server".
/serverInterface
Generates interfaces for server-side implementation of an ASP.NET Web Service. An interface is generated for each binding in the WSDL document(s). The WSDL alone implements the WSDL contract (classes that implement the interface should not include either of the following on the class methods: Web Service attributes or Serialization attributes that change the WSDL contract). Short form is '/si'. When using the /parameters option, this value is a <style> element that contains "servicerInterface".
/sharetypes
Turns on the type sharing feature. This feature creates one code file with a single type definition for identical types shared between different services (the namespace, name, and wire signature must be identical). Reference the services with "http://" URLs as command-line parameters or create a discomap document for local files. When using the /parameters option, this value is the<sharetypes> element and is either true or false.
/u[sername]:username
Specifies the user name to use when connecting to a server that requires authentication. When using the /parameters option, this value is the <username> element and contains a string.
/?
Displays command syntax and options for the tool.

A .wsdl file is an XML document written in an XML grammar called Web Services Description Language (WSDL). This file defines how an XML Web service behaves and instructs clients as to how to interact with the service.
You can obtain discovery documents for an XML Web service using the Web Services Discovery Tool (Disco.exe). The .discomap, .disco, .wsdl, and .xsd files produced by this tool can be used as input to Wsdl.exe.
When you use Wsdl.exe to create a proxy class, a single source file is created in the programming language that you specify. In the process of generating the source code for the proxy class, the tool determines the best type to use for objects specified in the service description. In some cases the tool uses a least-common-denominator approach for casting objects to a type. As a result, the generated type in the proxy class might not be what the developer wants or expects. For example, when Wsdl.exe encounters an ArrayList type in a service description, it creates an Object Array in the generated proxy class. To ensure correct object type casts, open the file containing the generated proxy class and change any incorrect object types to the expected object type.
  • The /parameters option specifies a file that contains elements that correspond to most of the command-prompt options. Some command-prompt options are available only in the /parameters file formats.
The XML file format accepted by the /parameters option is a series of elements inside an outer <wsdlParameters xmlns="http://microsoft.com/webReference/"> element. If command-prompt values are specified and a /parameters file is used that contains different options or values, the values specified at the command prompt are used. The <wsdlParameters xmlns="http://microsoft.com/webReference/"> element must contain a <nologo> element, a <parsableerrors> element, and a <sharetypes> element.
Several options are passed as child elements of the <webReferenceOptions> element, which must contain a <verbose> element. Other child elements of<webReferenceOptions> are:
  • <style>. Contains either "client", "server", or "serverInterface".
  • <schemaImporterExtension>. Contains any number of <type> elements.
  • <codeGenerationOptions>. Can take a space-delimited set of the following strings.
  • "properties"
  • "newAsync"
  • "oldAsync"
  • "order"
  • "enableDataBinding"
See the Examples section for some demonstrations of the /parameters option.

The following command creates a client proxy class in the C# language for the XML Web service.
wsdl http://hostServer/WebserviceRoot/WebServiceName.asmx?WSDL
The following command creates a client proxy class in the C# language for an XML Web service located at the specified URL. The tool saves the client proxy class in the file myProxyClass.cs.
wsdl /out:myProxyClass.cs http://hostServer/WebserviceRoot/WebServiceName.asmx?WSDL
The following command creates a client proxy class in the Microsoft Visual Basic language for an XML Web service located at the specified URL. The tool saves the client proxy class in the file myProxyClass.vb.
wsdl /language:VB /out:myProxyClass.vb http://hostServer/WebserviceRoot/WebServiceName.asmx?WSDL
  • The following example code shows a basic /parameters WSDL file with only the required elements written that can be used combined with a URL argument at the command prompt.
<wsdlParameters xmlns="http://microsoft.com/webReference/">
  <nologo>true</nologo>
  <parsableerrors>true</parsableerrors>
  <sharetypes>true</sharetypes>
</wsdlParameters>
WSDL documents are added in the /parameters WSDL file using the <documents> element, as the following code example demonstrates. Any number of<document> elements can be used inside the <documents> element.
<wsdlParameters xmlns="http://microsoft.com/webReference/">
  <nologo>true</nologo>
  <parsableerrors>true</parsableerrors>
  <sharetypes>true</sharetypes>
  <documents>
    <document>http://www.contoso.com/service.asmx?WSDL</document>
  </documents>
</wsdlParameters>
The following /parameters WSDL file demonstrates the use of the <codeGenerationOptions> and <style> elements inside the <webReferenceOptions>element. In this case, the file enables the new style of databinding in proxy code, and specifies a schema importer extension, that output is not to be verbose, and that Wsdl.exe is to create a client proxy.
<wsdlParameters xmlns="http://microsoft.com/webReference/">
  <nologo>true</nologo>
  <parsableerrors>true</parsableerrors>
  <sharetypes>true</sharetypes>
  <documents>
    <document>http://www.contoso.com/service.asmx?WSDL</document>
  </documents>
  <webReferenceOptions>
    <verbose>false</verbose>
    <codeGenerationOptions>properties newAsync enableDataBinding</codeGenerationOptions>
    <schemaImporterExtension>
      <type>MyNamespace.MyCustomImporterExtension,ExtensionLibrary</type>
    </schemaImporterExtensions>
    <style>client</style>
  </webReferenceOptions>
</wsdlParameters>

Creating a .NET Web Service


Microsoft .NET marketing has created a huge hype about its Web Services. This is the first of two articles on Web Services. Here we will create a .NET Web Service using C#. We will look closely at the Discovery protocol, UDDI, and the future of the Web Services. In the next article, we will concentrate on consuming existing Web Services on multiple platforms (i.e., Web, WAP-enabled mobile phones, and windows applications).
Why do we need Web Services?

What is a Web Service?
After buying something over the Internet, you may have wondered about the delivery status. Calling the delivery company consumes your time, and it's also not a value-added activity for the delivery company. To eliminate this scenario the delivery company needs to expose the delivery information without compromising its security. Enterprise security architecture can be very sophisticated. What if we can just use port 80 (the Web server port) and expose the information through the Web server? Still, we have to build a whole new Web application to extract data from the core business applications. This will cost the delivery company money. All the company wants is to expose the delivery status and concentrate on its core business. This is where Web Services come in.
Web Services are a very general model for building applications and can be implemented for any operation system that supports communication over the Internet. Web Services use the best of component-based development and the Web. Component-base object models like Distributed Component Object Model (DCOM), Remote Method Invocation (RMI), and Internet Inter-Orb Protocol (IIOP) have been around for some time. Unfortunately all these models depend on an object-model-specific protocol. Web Services extend these models a bit further to communicate with the Simple Object Access Protocol (SOAP) and Extensible Markup Language (XML) to eradicate the object-model-specific protocol barrier (see Figure 1).
Web Services basically uses Hypertext Transfer Protocol (HTTP) and SOAP to make business data available on the Web. It exposes the business objects (COM objects, Java Beans, etc.) to SOAP calls over HTTP and executes remote function calls. The Web Service consumers are able to invoke method calls on remote objects by using SOAP and HTTP over the Web.

Figure 1: SOAP calls are remote function calls that invoke method executions on Web Service components at Location B. The output is rendered as XML and passed back to the user at Location A.
How is the user at Location A aware of the semantics of the Web Service at Location B? This question is answered by conforming to a common standard. Service Description Language (SDL), SOAP Contract Language (SCL) and Network Accessible Specification Language (NASSL) are some XML-like languages built for this purpose. However, IBM and Microsoft recently agreed on the Web Service Description Language (WSDL) as the Web Service standard.
The structure of the Web Service components is exposed using this Web Service Description Language. WSDL 1.1 is a XML document describing the attributes and interfaces of the Web Service. The new specification is available at msdn.microsoft.com/xml/general/wsdl.asp.
The task ahead
The best way to learn about Web Services is to create one. We all are familiar with stock quote services. The NASDAQ, Dow Jones, and Australian Stock Exchange are famous examples. All of them provide an interface to enter a company code and receive the latest stock price. We will try to replicate the same functionality.
The input parameters for our securities Web service will be a company code. The Web service will extract the price feed by executing middle-tier business logic functions. The business logic functions are kept to a bare minimum to concentrate on the Web service features.
Tools to create a Web Service
The core software component to implement this application will be MS .NET Framework SDK, which is currently in beta. You can download a version from Microsoft. I used Windows 2000 Advance Server on a Pentium III with 300 MB of RAM.
The preferred Integration Development Environment (IDE) to create Web Services is Visual Studio .NET. However, you can easily use any text editor (WordPad, Notepad, Visual Studio 6.0) to create a Web Service file.
I assume you are familiar with the following concepts:
  • Basic knowledge of .NET platform
  • Basic knowledge of C#
  • Basic knowledge of object-oriented concepts
Creating a Web Service
We are going to use C# to create a Web Service called "SecurityWebService." A Web Service file will have an .ASMX file extension. (as opposed to an .ASPX file extension of a ASP.NET file). The first line of the file will look like

<%@ WebService Language="C#" class="SecurityWebService" %>
This line will instruct the compiler to run on Web Service mode and the name of the C# class. We also need to access the Web Service namespace. It is also a good practice to add a reference to the System namespace.

using System;
using System.Web.Services;
The SecurityWebService class should inherit the functionality of the Web Services class. Therefore, we put the following line of code:

public class SecurityWebService : WebService
Now we can use our object-oriented programming skills to build a class. C# classes are very similar to C++ or Java classes. It will be a walk in the park to create a C# class for anyone with either language-coding skills.
Dot-net Web Services are intelligent enough to cast basic data types. Therefore, if we return "int," "float," or "string" data types, it can convert them to standard XML output. Unfortunately, in most cases we need get a collection of data regarding a single entity. Let's take an example.
Our SecurityWebService stock quotes service requires the user to enter a company code, and it will deliver the full company name and the current stock price. Therefore, we have three pieces of information for a single company:
  1. Company code (data type - string)
  2. Company name (data type - string)
  3. Price (data type - Double)
We need to extract all this data when we are referring to a single stock quote. There are several ways of doing this. The best way could be to bundle them in an enumerated data type. We can use "structs" in C# to do this, which is very similar to C++ structs.

public struct SecurityInfo
 {
  public string Code;
  public string CompanyName;
  public double Price;
 }
Now we have all the building blocks to create our Web Service. Therefore, our code will look like.

<%@ WebService Language="C#" class="SecurityWebService" %>

using System;
using System.Web.Services;

public struct SecurityInfo
{
 public string Code;
 public string CompanyName;
 public double Price;
}

public class SecurityWebService : WebService
{
 private SecurityInfo Security;
 
 public SecurityWebService()
 {
  Security.Code = "";
  Security.CompanyName = "";
  Security.Price = 0;
 }

 private void AssignValues(string Code)
 {
  // This is where you use your business components. 
  // Method calls on Business components are used to populate the data.
  // For demonstration purposes, I will add a string to the Code and
  //  use a random number generator to create the price feed.
     
  Security.Code = Code;
  Security.CompanyName = Code + " Pty Ltd";
  Random RandomNumber = new System.Random();
  Security.Price = double.Parse(new System.Random(RandomNumber.Next(1,10)).NextDouble().ToString("##.##"));
 }


    [WebMethod(Description="This method call will get the company name and the price for a given security code.",EnableSession=false)]
 public SecurityInfo GetSecurityInfo(string Code)
 {
  AssignValues(Code);
  SecurityInfo SecurityDetails = new SecurityInfo();
  SecurityDetails.Code = Security.Code;
  SecurityDetails.CompanyName = Security.CompanyName;
  SecurityDetails.Price = Security.Price;
  return  SecurityDetails;
 }

}

Remember, this Web Service can be accessed through HTTP for any use. We may be referring to sensitive business data in the code and wouldn't want it to fall into the wrong hands. The solution is to protect the business logic function and only have access to the presentation functions. This is achieved by using the keyword "[Web Method]" in C#. Let's look at the function headers of our code.

[WebMethod(Description="This......",EnableSession=false)]
public SecurityInfo GetSecurityInfo(string Code)
This function is exposed to the public. The "description" tag can be used to describe the Web Service functionality. Since we will not be storing any session data, we will disable the session state.

private void AssignValues(string Code)
This is a business logic function that should not be publicly available. We do not want our sensitive business information publicly available on the Web. (Note:- Even if you change the "private" keyword to "public," it will still not be publicly available. You guessed it, the keyword "[Web Method]" is not used.)
We can use the business logic in this function to get the newest stock price quote. For the purpose of this article I have added some text to the company code to create the company name. The price value is generated using a random number generator.
We may save this file as "SampleService.asmx" under an Internet Information Service (IIS)-controlled directory. I have saved it under a virtual directory called "/work/aspx." I'll bring it up on a Web browser.

Figure 2
This is a Web page rendered by the .NET Framework. We did not create this page. (The page is generated automatically by the system. I did not write any code to render it on the browser. This graphic is a by-product of the previous code.) This ready-to-use functionality is quite adequate for a simple Web Service. The presentation of this page can be changed very easily by using ASP.NET pagelets and config.web files. A very good example can be found at http://www.ibuyspy.com/store/InstantOrder.asmx.
Notice a link to "SDL Contract." (Even if we are using WSDL, .NET Beta still refers to SDL. Hopefully this will be rectified in the next version). This is the description of the Web Service to create a proxy object. (I will explain this in the next article.) This basically gives an overview of the Web Service and it's public interface. If you look closely, you will only see the "Web-only" methods being illustrated. All the private functions and attributes are not described in the SDL contract. The SDL contract for the SecurityWebService can be found in Appendix A.
How do we use a Web Service?
Now we can use this Web Service. Let's enter some values to get a bogus price feed.

Figure 3
By clicking the Invoke button a new window will appear with the following XML document

Figure 4
This is how the Web Service releases information. We need to write clients to extract the information from the XML document. Theses clients could be
  1. A Web page
  2. A console / Windows application
  3. A Wireless Markup Language (WML) / WMLScript to interact with mobile phones
  4. A Palm / Win CE application to use on Personal Digital Assistants (PDAs).
I will explain this process in the next article.
You can also call the Web Service directly using the HTTP GET method. In this case we will not be going through the above Web page and clicking the Invoke button. The syntax for directly calling the Web Service using HTTP GET is
http://server/webServiceName.asmx/functionName?parameter=parameterValue
Therefore, the call for our Web Service will be
http://localhost/work/aspx/SampleService.asmx/GetSecurityInfo?Code=IBM
This will produce the same result as clicking the Invoke button.
Now we know how to create a Web Service and use it. But the work is half done. How will our clients find our Web Service? Is there any way to search for our Web Service on the Internet? Is there a Web crawler or a Yahoo search engine for Web Services? In order to answer these questions we need to create a "discovery" file for our Web Service.
Creating a Discovery file
Web Service discovery is the process of locating and interrogating Web Service descriptions, which is a preliminary step for accessing a Web Service. It is through the discovery process that Web Service clients learn that a Web Service exists, what its capabilities are, and how to properly interact with it. Discovery file is a XML document with a .DISCO extension. It is not compulsory to create a discovery file for each Web Service. Here is a sample discovery file for our securities Web Service.

<?xml version="1.0" ?>
<disco:discovery xmlns:disco="http://schemas.xmlsoap.org/disco/">
    <scl:contractRef ref="http://localhost/work/aspx/SampleService.asmx?SDL"/>
</disco:discovery>
We can name this file "SampleService.disco" and save it to the same directory as the Web Service. If we are creating any other Web Services under the "/work/aspx" directory, it is wise to enable "dynamic discovery." Dynamic discovery will scan for all the *.DISCO files in all the subdirectories of "/work/aspx" automatically.

<?xml version="1.0" ?>
    <dynamicDiscovery xmlns="urn:schemas-dynamicdiscovery:disco.2000-03-17">
</dynamicDiscovery> 
By analyzing the discovery file we can find where the Web Services reside in the system. Unfortunately both these methods require you to know the exact URL of the discovery file. If we cannot find the discovery file, we will not be able to locate the Web Services. Universal Description, Discovery, and Integration (UDDI) describes mechanisms to advertise existing Web Services. This technology is still at the infant stage. UDDI is an open, Internet-based specification designed to be the building block that will enable businesses to quickly, easily, and dynamically find and transact business with one another using their preferred applications. A reference site for UDDI is http://uddi.microsoft.com.
There have been a lot of Web Services written by developers. www.xmethods.com is one of the sites that has an index of Web Services. Some developers are building WSDL search engines to find Web Services on the Web.
Deploying a Web Service
Deploying the Web Services from development to staging or production is very simple. Similar to ASP.NET applications, just copy the .ASMX file and the .DISCO files to the appropriate directories, and you are in business.
The future of the Web Services
The future looks bright for the Web Service technology. Microsoft is not alone in the race for Web Service technology. Sun and IBM are very interested. There are SOAP toolkits available for Apache and Java Web servers. I believe Web Services needs a bit of work, especially the Web Service discovery process. It is still very primitive.
On a positive note, Web Services have the potential to introduce new concepts to the Web. One I refer to as "pay per view" architecture. Similar to pay-TV, we can build Web sites that can generate revenue for each request a user sends (as opposed to a flat, monthly subscription). In order to get some data, we can sometimes pay a small fee. Commercially this could be handy for a lot of people.
Examples
  • Online newspaper sites can publish a 10-year-old article with a $2 "pay per view" structure.
  • Stock market portals can itemize every user portfolio for every single stock quote and build pricing and discount structures.
And the list goes on ...
On a very optimistic note, Web Services can be described as the "plug and play" building blocks of enterprise Business to Business (B2B) Web solutions.
Appendix A

  <?xml version="1.0" ?> 
  <serviceDescription xmlns:s0="http://tempuri.org/" name="SecurityWebService" targetNamespace="http://tempuri.org/" 
 xmlns="urn:schemas-xmlsoap-org:sdl.2000-01-25">
  <soap xmlns="urn:schemas-xmlsoap-org:soap-sdl-2000-01-25">
  <service>

  <addresses>
  <address uri="http://localhost/work/aspx/SampleService.asmx" /> 
  </addresses>
  <requestResponse name="GetSecurityInfo" soapAction="http://tempuri.org/GetSecurityInfo">
  <request ref="s0:GetSecurityInfo" /> 
  <response ref="s0:GetSecurityInfoResult" /> 
  <info>This method call will get the company name and the price for a given security code.</info> 
  </requestResponse>

  </service>
  </soap>
  <httppost xmlns="urn:schemas-xmlsoap-org:post-sdl-2000-01-25">
  <service>
  <requestResponse name="GetSecurityInfo" href="http://localhost/work/aspx/SampleService.asmx/GetSecurityInfo">
  <request>

  <form>
  <input name="Code" /> 
  </form>
  </request>
  <response>
  <mimeXml ref="s0:SecurityInfo" /> 
  </response>

  <info>This method call will get the company name and the price for a given security code.</info> 
  </requestResponse>
  </service>
  </httppost>
  <httpget xmlns="urn:schemas-xmlsoap-org:get-sdl-2000-01-25">
  <service>

  <requestResponse name="GetSecurityInfo" href="http://localhost/work/aspx/SampleService.asmx/GetSecurityInfo">
  <request>
  <param name="Code" /> 
  </request>
  <response>
  <mimeXml ref="s0:SecurityInfo" /> 
  </response>

  <info>This method call will get the company name and the price for a given security code.</info> 
  </requestResponse>
  </service>
  </httpget>
  <schema targetNamespace="http://tempuri.org/" attributeFormDefault="qualified" 
 elementFormDefault="qualified" xmlns="http://www.w3.org/1999/XMLSchema">
  <element name="GetSecurityInfo">

  <complexType>
  <all>
  <element name="Code" xmlns:q1="http://www.w3.org/1999/XMLSchema" type="q1:string" nullable="true" /> 
  </all>
  </complexType>
  </element>

  <element name="GetSecurityInfoResult">
  <complexType>
  <all>
  <element name="result" type="s0:SecurityInfo" /> 
  </all>
  </complexType>

  </element>
  <complexType name="SecurityInfo">
  <all>
  <element name="Code" xmlns:q2="http://www.w3.org/1999/XMLSchema" type="q2:string" nullable="true" /> 
  <element name="CompanyName" xmlns:q3="http://www.w3.org/1999/XMLSchema" type="q3:string" nullable="true" /> 
  <element name="Price" xmlns:q4="http://www.w3.org/1999/XMLSchema" type="q4:double" /> 
  </all>

  </complexType>
  <element name="SecurityInfo" type="s0:SecurityInfo" /> 
  </schema>
  </serviceDescription>


About the Author
Chris Peiris is a systems architect for IT & E-Commerce in Melbourne, Australia. He has been designing and developing MS Web solutions since 1995. His expertise lies in developing scalable, high-performance Web solutions for financial institutions and media groups. He also teaches at Monash University in Caulfield, Australia. His core skills are C++, Java, .NET, DNA, MTS, Site Server, Data Warehousing, WAP, and SQL Server. Hobbies include cricket, teaching, and reading books. Chris has a Bachelor of Computing, Bachelor of Business (Accounting), and Masters of Information Management Systems.