Sie sind auf Seite 1von 116

Webservices with C#

Gerhard Juen

University of Applied Sciences Gelsenkirchen


Bocholt Campus
Faculty Electrical Engineering
February 2006
Webservices with C# 2

1 Introduction 4 3 Stateless/statefull Webservice 50


1.1 A simple local Service 4 3.1 Stateless Webservice 50

1.2 The Remote Service Idea 5 3.2 Session/Application related State 52

1.3 Existing remote Service Techniques 11 3.3 A Webservice with Application State 52

1.4 Internet/Intranet Protocol Stack 12 3.4 A Webservice with Session State 56

1.5 Excursus: Dynamic interactive Web 3.5 Exercise 58


Applications 13 4 Transfer of sophisticated Data Structures 59
1.6 Webservice Transport Idea 14 4.1 Excursus: Serialising/deserialising of data 59
2 Getting started: A simple Webservice 16 4.2 Serialising of Arrays 70
2.1 Webservice Server Code 16 4.3 Exercise 73
2.2 Publishing the Webservice 17 4.4 Serializing of a chained List 74
2.3 Checking the Webservice with a Browser 17 4.5 Call by Value 78
2.4 Name space qualified Webservice 19 4.6 Complex return Value 79
2.5 Describing the Webservice 24 4.7 Exercise 82
2.6 WEB-Browser as Client 25 5 Soap Protocol 85
2.7 Automatic Client Proxy Generation / 5.1 Webservice with Transport Sniffer 85
WSDL Document 27
5.2 The add call SOAP messages 87
2.8 The C# Client 29
5.3 The Calculator WSDL 89
2.9 The generated Proxy Class 36
6 Asynchronous Webservice 100
2.10 Consuming Webservices via HTTP Proxy 39
6.1 Blocking vs. non Blocking Call 100
2.11 Exceptions 43
6.2 Calculator with non blocking add call 104
2.12 Excercises 46
6.3 Exercise 109

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 3

7 Architectures 111 7.2 Communication across different Platforms 115


7.1 Software Interface for Web Site 111 7.3 News Provider 115

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 4

1 Introduction
1.1 A simple local Service
A "local service" Calculator offers a method add which adds two integers:

// Class which provides the service => "server"


class Calculator {
public int add (int i1, int i2) { // with method add
return i1+i2;
}
}

// Class which consumes the service => "client"


class CalculatorClient {
static void Main(string[] args) {
Calculator calculator = new Calculator();
int retVal=calculator.add(10,20) // service call
Console.WriteLine(retVal);
}
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 5

1.2 The Remote Service Idea

Local service call *) Remote service call*)


retVal=calculator.add(20,30) retVal=calculator.add(20,30)

calculator
calculator
client
client
request response request response

response
calculator calculator calculator
proxy skeleton
request
request response

calculator

machine A (client + server) machine A (client) machine B (server)

*) "Local/Remote service call" = "Call of a method of a local/remote object"


(shortcut: "local/remote method call").

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 6

Steps of a local method call


calculator client calculator
1) calculator=new Calculator()

2) calculator.add(10,20)

3)
carry out
add(10,20)

4) return value 30
5)

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 7

Steps/phases of a remote method call


calculator client calculator proxy calculator skeleton calculator

1) calculator=new Calculator()

2) calculator.add(10,20)
3) prepare request message
{add,10,20}

4) request message {add,10,20}


5) unpack request message

6) calculator=new Calculator()

7) calculator.add(10,20)
8) carry out
add(10,20)
9) return value 30

10) prepare response message


{return value 30}
11) {return value 30}

12) unpack response message


13) return value 30

14)

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 8

1) The calculator client creates an instance of class Calculator


(which looks from outside like a calculator but is internally a calculator
proxy). This step is only necessary once before the first call.
2) The calculator client calls the desired calculator method with the
appropriate parameters, e.g. calculator.add(20,30),
which is a call to the calculator proxy created in step 1).
3) The calculator proxy
- receives the call,
- packs method name (add) and parameters (20,30) into a
"request-message" and ..
4) .. sends this request message over a network (Intranet/Internet)
to the server machine.
5) On the server machine the calculator skeleton object
- receives the request message,
- decodes (unpacks) it, ..
6) .. creates a new object calculator of the class Calculator
(which is really a calculator which contains the service) and ..
7) .. executes the calculator's local method add(20,30).
8) The local calculator computes the sum and ..
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 9

9) .. returns it to the calculator skeleton.


10) The calculator skeleton packs the return value into a
"response message" and ..
11) .. sends it back to the calculator proxy.
12) The calculator proxy unpacks the response message and ..
13) .. uses the received value as return value of the calculator client's
add(20, 30) call.
14) The still waiting calculator client leaves the add method
with the requested sum as return value.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 10

Requirement for transparency of remote method call


The transparency concerns the red part of the diagram on the preceding page.

Calculator proxy and calculator skeleton

are transparent for

calculator client and calculator (server)

• From the outside calculator proxy looks like calculator:


- Calculator proxy class name is Calculator
- Calculator proxy has method public int add(int .., int ..)
• Server side Calculator class is the original local Calculator class,
i.e. the calculator service developer has not to care about whether the service
is accessed by local or remote clients.
• There exist tools to create calculator proxy and calculator skeleton
automatically.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 11

1.3 Existing remote Service Techniques


The remote service idea is old and there exist many techniques
(with different features and comfort).
Rough classification of remote service techniques:
• Remote procedure calls (RPC)
• Remote objects

Remote Procedure Call (RPC) Remote Objects


DDE-RPC DCOM
(Distributed Component Object Model)
ONL-RPC CORBA
(Common Object Request Broker Architecture)
XML-RPC RMI
(Remote Method Invocation)
SOAP, Webservices
(Simple Object Access
Protocol)*)
*) It's neither simple nor object

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 12

1.4 Internet/Intranet Protocol Stack


HTTP Server/Client,
Application SMTP-Server/Client, ....
webservice based Application
client server Message
communication Application HTTP SMTP POP3
Layer (5)
IMAP4 TELNET FTP
socket based Stream (TCP) or Datagram (UDP)
client server -> IP-Adr. + PortNr.
communication TCP UDP
Transport
Layer (4) connection packet
oriented oriented

Data packages
-> IP-Adresse (193.175.175.111)
Network IP
Layer (3) Internet-Protocol
Ethernet data packages
-> card (MAC) adress
Link Hardware Interface
Layer (2) (Ethernet-card)

Physical
Transmission Line
Layer (1)

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 13

1.5 Excursus: Dynamic interactive Web Applications

calc.php

POST /calc.php HTTP/1.0


calc.php
i1=20&i2=30
i1=20&i2=30
webbrowser webserver PHP
processor
<html>
HTTP/1.0 200 OK <body>
<html> 20+30=50
<body> </body>
20+30=50 </html>
</body>
</html> red: HTTP-transport frame

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 14

1.6 Webservice Transport Idea

POST ENDPOINT HTTP/1.1


calculator client
REQUEST
REQUEST
calculator proxy webserver calculator skeleton

RESPONSE
HTTP/1.1 200 OK calculator (server)

RESPONSE
Client machine Server machine

red stuff is the HTTP transport frame for he Webservice


ENDPOINT Addresses the file/script etc. which contains the service
REQUEST Contains service name, method name and parameters
packed into an XML-document
RESPONSE Returns "result" data packed into an XML-document

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 15

Why HTTP?
• Use of existing webservers,
• Passes most firewalls (uses WWW transport).

Why text based (XML) content?


Text is able to encode/decode most "elementary" data primitives
• String: "Hello world"
• Integers: "12376"
• Float: "1.276E16"
• Binary data (as base64 coded binary: "0XADVGF==" or CDATA Section)

Why XML?
• The document includes structure information.
• XML-parsers are available for most programming languages.
• Provides even the representation of binary data (see above).
• Provides the representation of data which should not be parsed by the
XML-parser such as XML or HTML-data (CDATA construct).

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 16

2 Getting started: A simple Webservice


2.1 Webservice Server Code
Webservice which adds two numbers
A <%@ WebService Language="C#" class="Calculator" %>

B using System.Web.Services;

C public class Calculator


{
D [WebMethod]
public int add (int i1, int i2)
{
return i1+i2;
}
F }
A means that the C# code in this file contains a class Calculator
which provides a webservice with the name Calculator.
A webservice class has at least one method publicly accessible
by "webservice technique" ("WebMethod"), line D.
(Remark: The file might contain more than one class,
only one of these may play the webservice role).
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 17

B includes the namespace System.Web.Services which contains the


definition of the [WebMethod] attribute used in line D.
C..F define the class which forms the webservice Calculator announced in
the headline A.
D defines the method add as web enabled method ("webmethod") of the
webservice Calculator.
2.2 Publishing the Webservice
• Put the webservice code into the file Calculator.asmx.
Remark: The extension asmx denotes that the file contains a webservice.
• Store the file into a directory publicly accessible from the WEB via the IIS.
2.3 Checking the Webservice with a Browser
Take a Browser, e.g. the Internet Explorer:
• Enter in the URL field
http://YourWebRoot/Calculator.asmx
• Response on the screen:

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 18

A
C
B

A The name of the webservice.


B List of all available webservice methods:
For each method a link is presented leading to a browser based frontend.
C A link to the webservice description file (WSDL-File). This is an XML
document with all information which is required to consume the
webservice. With this WSDL-file the Visual Studio can generate the
required service proxy class automatically.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 19

D A hint, that our webservice should use a namespace in order to give it a


world wide unique name.
2.4 Name space qualified Webservice

Why should we use worldwide unique webservice names?


Webservice technique is used as a "public" communication technique.
Computers talk to computers all over the world:
• Companies exchange documents
(orders, invoices, product data, ..)
• Applications connect over public interfaces
to services such as Ebay, Google Earth, ..
In order to avoid possible conflicts between different services with the same
name each webservice should have a unique name.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 20

Namespace principle

unique in the classroom

Germany.Bocholt.Juen.Gerhard
unique in the world
Where do we find namespaces
• namespace organisation of C# classes:
System.IO
System.Web.Services
;
specialization -->
• package organisation of Java classes
• namespace in XML-documents

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 21

Generation of a unique webservice name


A simple strategy to generate a guaranteed unique namespace
is to take our company’s internet address
http://juen.com

protocol 2nd level top level


domain domain

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 22

Proposed namespaces
For Juen:
com.juen
If necessary with additional qualifiers, such as
com.juen.WebserviceCourse
com.juen.ControlSystemCourse
com.juen.BookShop

For students
de.fh-gelsenkirchen.yourname
fi.cop.yourname …

Remark:
Often you find namespaces which look like web-adresses
e.g. the default namespace selected by the .NET framework:
http://tempuri.org/
Such addresses normally do not lead you anywhere
(and nobody would expect this)

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 23

Fully namespace qualified Calculator webservice:


Introduce the bold line in Calculator.asmx:
[WebService (Namespace="YourChosenNamespace")]
public class Calculator
:

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 24

2.5 Describing the Webservice

Describing the webservice


[WebService (Description="Simple integer calculator")]
public class Calculator
:

[WebService (Namespace="YourChosenNamespace",
Description="Simple integer calculator")]
public class Calculator
:

Describing the webmethods


[WebMethod (Description="Adds two numbers")]
public int add (int i1, int i2)
:

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 25

2.6 WEB-Browser as Client


We want to test a webservice before having developed a corresponding
"webservice client".
For that purpose the ASP.NET application server provides a WEB browser
frontend:
If we click on the Calculator's webservice add method, we see:

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 26

We insert two numbers (20 and 30) click the Invoke button and get

The webservice response XML-document is sent to the browser as it is,


i.e. without any transformation to some user readably format (HTML).
Explanation of the response document:
• The first line (the so called “Prologue”) tells us, that we have an XML-
document which refers to the XML version 1.0 standard and which uses UTF-8
character encoding.
• The next line defines an element int with content 50.
• The namespace qualification xmlns="com.juen" tells us that the int
element is defined in the com.juen namespace. This does not really make
sense here because we introduced this namespace in order to have an
individual calculator not an individual integer format.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 27

2.7 Automatic Client Proxy Generation / WSDL Document

POST ENDPOINT HTTP/1.1


calculator client
REQUEST
REQUEST
calculator proxy webserver calculator skeleton

RESPONSE
HTTP/1.1 200 OK calculator (server)

RESPONSE
Client machine Server machine

The calculator client C# program needs a calculator proxy class.


All webservice toolkits provide tools which create this proxy automatically
on the basis of the service related WSDL-file.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 28

Starting Point is the WSDL-file


The publicly accessible WSDL file contains all information about the
webservice interface. It is generated on the server automatically "on demand".
Example: URL of the Calculator webservice WSDL-file
http://YourWebRoot/Calculator.asmx?WSDL
The content of this WSDL-file is not interesting at this moment.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 29

2.8 The C# Client

Step 1: Create the console application project frame (Visual Studio)

Project type: Visual C#, Windows, Console Application


Name: CalculatorClient (becomes also the Default

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 30

Namespace)
Location: YourVisualStudioProjectsRoot\WebserviceClients

Step 2: Create the calculator proxy class


• Menu bar: Project -> Add Web Reference
• Enter the WSDL-document URL in the URL-field

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 31

• Press Go
• In the field "Web reference name" enter as name for this reference:
RemoteCalculator
Recommendation: Never choose simply the service’s name (in our case
Calculator) in order to avoid name conflicts between the proxy class name
and the proxy class namespace
ProjectDefaultNamespace.WebReferenceName
automatically generated by VisualStudio.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 32

• Press "Add Reference" button

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 33

What happens behind the curtain?


• Visual Studio creates a sub directory
Web reference\RemoteCalculator with content
Calculator.wsdl a copy of the WSDL document
Reference.cs the proxy class Calculator
• adds Reference.cs to the project
• includes additional references to some DLL's needed for "webservice
support".

Step 3: Insert the client code in Program.cs


• Include the bold lines into the Main method
• Remove not needed using lines

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 34

using System;
using System.Collections.Generic;
using System.Text;
A using CalculatorClient.RemoteCalculator;
B //using OtherRemoteCalculator;

namespace CalculatorClient
{
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Console.WriteLine(calculator.add(20,30));
}
{
}
A Tells the compiler, to look for classes also in the namespace
CalculatorClient.RemoteCalculator. This concerns the class
Calculator with full name
CalculatorClient.RemoteCalculator.Calculator
B Switching between different Calculators (with the same interface) can
simply be done by substituting the line A by another using line.
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 35

Step 4: Compile and start the program


.. and you see (after some waiting time) a simple 50 on the console.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 36

2.9 The generated Proxy Class

A glance into the client side proxy class Calculator


Select the Class View tab at the bottom of the Solution
Explorer window:

Project name

Calculator client namespace


Calculator client class

Calculator proxy namespace

Calculator proxy class

Full proxy class name: Calculator.RemoteCalculator.Calculator


Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 37

Content of Calculator.RemoteCalculator.Calculator:
namespace CalculatorClient.RemoteCalculator {
:
public class Calculator :
System.Web.Services.Protocols.SoapHttpClientProtocol
{
public Calculator() {
A this.Url = global::
CalculatorClient.Properties.Settings.Default.
CalculatorClient_RemoteCalculator_Calculator;
}
B public int add(int i1, int i2) {
object[] results = this.Invoke(
"add", new object[] {i1, i2});
return ((int)(results[0]));
}
}
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 38

A The calculator proxy contains an instance variable Url, which contains


the URL where we reach the remote service. In contradiction to earlier
versions of Visual Studio the Url-string is no longer inserted directly, but as
reference to a global setting (file Settings.cs), where we find the line:
[global::System.Configuration.DefaultSettingValueAttrib
ute

("http://127.0.0.1/WebServices/Calculator.asmx")]
B As expected, the proxy’s add method has the same signature as the
original local service call (i.e. the Calculator’s add method).

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 39

2.10 Consuming Webservices via HTTP Proxy

Webservice client in Internet

Internet

Webservice direct communication Webservice


client server
Public IP-adress Public IP-adress
80.117.60.111 193.175.175.141

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 40

Webservice client in Intranet

Intranet Internet

direct direct
Webservice communication HTTP communication Webservice
client proxy server
Local IP-adress Local IP-adress Public IP-adress Public IP-adress
192.168.60.111 192.168.60.68 80.15.75.141 193.175.175.141

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 41

Typical situation:
• Webservice client runs within a local Intranet
(all PC's have only local IP-addresses)
• The public webservice in the internet you are interested in
is not directly accessible
(no direct connection between local and public IP-addresses possible)

.NET framework default


Reads the HTTP proxy configuration out of the Internet Explorer's proxy
parameters. It is used in 2 situations:
• by the client when executing the webservice call,
• by the Visual Studio when fetching the WSDL-document
for generating the service proxy class.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 42

.NET framework special


You can overwrite the default HTTP-proxy by editing machine.config in
directory C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG:

<configuration>
<system.net>
<defaultProxy>
A <proxy usesystemdefault="true"/>
</defaultProxy>
</system.net>
<configuration>

Substitute line A by
<proxy usesystemdefault="false"
proxyaddress="http://127.0.0.1:3128"
bypassonlocal="true"
/>

if your HTTP-proxy for example hears on port 3128 at


IP-address 127.0.0.1.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 43

2.11 Exceptions

Exceptions can be divided into


• service related exceptions
Example "Division by 0".
This exception type also occurs for local method calls.
• communication related exceptions
Example "Broken Connection".
This exception type only occurs for remote method calls.

Catch the exceptions


It is highly recommended to embed the remote method call into a try catch
construct:
try
{
calculator.divide(3,0); // provides next rounded int
}
catch (Exception e)
{
Console.WriteLine(e.Message)
}
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 44

In case of a local method call you might get s.th. similar to:

Attempted to divide by zero.

In case of a remote method call you might get s.th. similar to

Server was unable to process the request. --->


Attempted to divide by zero.

Behind the curtain


• Exceptions which occur on the server side while processing the request are
always packed into a SoapException and sent back to the client.
• Therefore, the client side remote method call may only throw an exception of
type SoapException.

Passing own error messages to the client


The service developer should use SoapException (Defined in
System.Web.Services.Protocols) if the service cannot carried out due to
some error situation, e.g. because the client sent incompatible parameters.
The technique is to throw a SoapException with an own message text.
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 45

A using System.Web.Services.Protocols
:
:
if (i1<0) throw new SoapException(
B "i1<0 not allowed",
C SoapException.ClientFaultCode);
A this line includes the namespace System.Web.Services.Protocols
to which the SoapException class belongs.
B The first parameter defines our error text
C The second parameter allows to classify the error:
SoapException.ClientFaultCode
means that the error has been caused by wrong request parameters,
i.e. the client should modify the request and then try it again.
SoapException.ServerFaultCode
means that the fault has been caused by some server related
condition, e.g. by a inactive server database. In this case the client
should come back later.
The client side message (e.Message) reads
i1<0 not allowed

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 46

2.12 Excercises
2.12.1 Integer Calculator
• Extend the Calculator webservice with a two integer subtract, multiply and
divide method.
• Check this webservice with a browser.
• Extend the existing C# test client.
• Check what happens if you call calculator.div(10,0).
• Include your own error handling in the div method:
- Throw a Soap-Exception in the calculator server in case of the second
parameter equal to zero.
- Catch this error in the Client
Hint:
If you change the webservice “interface” you have to update the web reference
at client side in order to get an actual version of the service proxy.
Change the interface means one of the following:
• you modify the signature of an existing webmethod
• you delete an existing webmethod
• you include a new webmethod
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 47

2.12.2 Float Calculator


• Create a webservice FloatCalculator with four methods
add, subt, mult, and div.
• Check this webservice with a browser.
• Check this service with an own C# test client.

Specified standards for the client:


Name of Project: FloatCalculatorClient
Name of web reference: RemoteFloatCalculator

Hint:
All „float“ variables should be declared as float.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 48

2.12.3 SMS-Provider
Develop a client for the SMS-Provider service with the WSDL
http://193.175.197.65:8080/Sms.jws?wsdl
Try to find out which parameters the not commented send method expects.

Specified standards for the client:


Name of Project: SmsClient
Name of web reference: RemoteSms

Remark for the Finnish course


The phone number has to start with the international code for Finland from
Germany’s view because the service is located in Germany.
An example for such a phone number: 00358 44 4492534
(Remark: Test your client not with this number but with your own number).

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 49

2.12.4 Finnish German Translator


Develop a client for the Finnish German translator with the WSDL
http://193.175.197.65/ina/juen/webservices/finger.asmx?wsdl
If you like: develop a GUI client.

Specified standards for the client:


Name of project: FingerClient
Name of web reference: RemoteFinger

Behind the curtain:


The service realises a browser like communication with
http://www.tranexp.com:2000/Translate/result.shtml

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 50

3 Stateless/statefull Webservice
3.1 Stateless Webservice
So far all our webservices implement a stateless "remote procedure call". Each call
• creates on the server its own service object
• executes the service (calls the remote method) and
• destroys the service object afterwards.

The remote object lives only during a single remote call

Subsequent calls never see the same object. Consequence: You cannot store
information in the service object which is passed through the sequence of calls.
This is the reason to classify webservice/soap as remote procedure call technique
instead of remote object technique.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 51

Stateless webservice, type 1


The service is stateless (such as all the above calculators and translators).

Stateless webservice, type 2


Example:
Webservice - Interface to an electronic warehouse. Your current shopping cart
content is stored in the database.
Characteristics:
The webservice realises only a stateless interface to some statefull service
which lies outside the webservice scope. The state of the statefull service is
part of the business process and stored e.g. in a database.
Normally this would be the standard situation. Therefore, we do not really need
statefull webservices?

Minimum state webservice


If the state is related to the individual clients (such as the shopping cart in the
electronic warehouse) the client needs at least some identification code in
order to identify him through the subsequent calls of a multi step service.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 52

3.2 Session/Application related State


There are two types of state:
• User ("session")-related data
stay alive during subsequent webservice calls. Examples:
- user's actual content of the shopping cart in an electronic warehouse,
- user's accumulated number of calls,
- user's maximum offer in an electronic auction.
• Webservice ("application") related data
are common for all users of the particular webservice. Examples:
- number of the currently connected users,
- maximum offer in an electronic auction,
- actual contributions within a chat.
3.3 A Webservice with Application State

Example “Accumulator”:
The webservice provides an integer accumulator which can be resetted and
incremented from remote. The increment call carries out the increment and
returns the accumulator content.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 53

Server
<%@ WebService Language="C#" class="Accumulator" %>
using System.Web.Services;

[WebService(Namespace="com.juen")]
A public class Accumulator : WebService
{
[WebMethod]
public void reset() {
Application["accValue"]=0;
}

[WebMethod]
public int increment (int inc) {
B int accValue=inc;
C if (Application["accValue"]!=null) {
D accValue+= (int) Application["accValue"];
}
E Application["accValue"]=accValue;
return accValue;
}
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 54

A Our service class is derived from the class WebService from which we
use the property Application. Application is a “container” for
objects. An object put into the container exsist as long as the application
server is running. Furthermore, all these objects are global in the sense
that they can be read and written in all server side Accumulator
instances.
D..E The application variables stored in Application can be elementary data
types such as integers as well as references to complex objects.
In our application we store a simple integer i.e. accValue.
Each application variable is addressed via a freely chosen keyword
Application["some_explaining_keyword"]
in our case
Application["accValue"]
D As Application["..."] may store references to arbitrary objects we
have to cast the value returned by the read operation to the data type we
expect, i.e. int in our case because we know that we have put an int
into the container.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 55

C, D If there does not yet exist an accumulated sum


(Application["accValue"]==null) it becomes the sent increment as
initial value. Otherwise, we really add the increment value to the already
existing accumulated sum.

Test client (only the relevant lines):


A Accumulator acc = new Accumulator();
// acc.reset(); // if you like
Console.WriteLine(acc.increment(10));
Console.WriteLine(acc.increment(20));
Console.WriteLine(acc.increment(30));
Console.WriteLine(acc.increment(30));
All the increments above act upon a server side variable
• which is common for all clients and
• which stays alive through subsequent service calls.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 56

3.4 A Webservice with Session State


Storing session state is similar to storing application state.

Session related accumulator (server side):


A [WebMethod (EnableSession = true)]
public void reset()
{
B Session["accValue"]=0;
}
B Instead of Application["..."] for application related data we use
Session["..."] for session related data.
A Important: Session state has to be enabled individually for each
webmethod which accesses the Session property.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 57

Session related accumulator (client side):


Add the following line to your code such that it is called before the first
webservice call:
acc.CookieContainer = new System.Net.CookieContainer();
This line introduces a cookie mechanism on the client side in order
• to receive the session related data from the server,
• to store them in the client process and
• to send them back to the server in the next webservice call.
The mechanism is transparent for the webservice client programmer.

Lifetime
The session state is cleared when the client program ends.

Compability within the webservice world


It might be (I did not check it) that the session state feature is not compatible
with other webservice client implementations (Java Axis, NuSoap, SoapLite ..).

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 58

3.5 Exercise
• Develop a webservice SimpleChat (server + client) with 4 methods
public void setPrivateText(string text);
public string getPrivateText();
public void setPublicText(string text);
public string getPublicText();
The transferred text is stored as session (private) or application (public)
variable.
• Act with two clients against this service and show that
the private text really remains private and that
the public text is really public.
• Show by experiments that
session variables are deleted on client task exit and
application variables are not deleted on client task exit.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 59

4 Transfer of sophisticated Data Structures


4.1 Excursus: Serialising/deserialising of data
Request parameter flow

sender receiver

complex data complex data


structure structure

serialising deserialising
(marshalling) (unmarshalling)
bytestream
linear byte linear byte
sequence transport sequence

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 60

Worst case situation: Client and Server run on different platforms


Client and server
• have been developed in different programming languages
(e.g. Visual Basic and Java)
• run on different hardware
(e.g. Pentium PC and Sun workstation)
• run on different operating systems
(e.g. Windows and Linux)

Problem 1: Data might have different binary representation on different machines


Different machines might have
• different length of integer numbers (2 / 4 byte)
• different byte-order for integer numbers (low / high byte order)
RAM address 1300hex 1301hex
Content 02hex 10hex
0210hex = 528 Intel-processor ("Little Endian")
1002hex = 4998 Motorola processor ("Big Endian")
• different length of float numbers (4 / 8 byte)

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 61

• different binary representation of float numbers


• different character coding
(ASCII, LATIN-1, CP1252, UTF-8, UTF-16, UNICODE ..)
• different alignment within a data structure
class test
{
char c; // occupies 4 byte on a 32bit machine
// 2 byte on a 16bit machine
float x;
}

It is not possible to transfer simply the byte representation of data


(neither complex nor simple) from one machine to the other.

Problem 3: Mapping n-dimensional data structure to a 1 dimensional byte stream


n dimensions
(array with more than one index, data tree structures)

1 dimension (byte stream)

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 62

complex data structure

A D H

B C E

F G
Possible serialisation:
A B C D E F G H (or reverse)
A D H B C E F G (or reverse)
A B C D H E F G (or reverse)
:
Questions:
Which one to take?
How to tell the remote partner about my choice? ..
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 63

Problem 4: Data structure with pointers (references)


A pointer (reference) refers to an address in the address space of the sender.
Even a correct transfer of this address to the receiver would not make any
sense.
Transfer of pointers (references means)
• Transfer the referenced data.
• Allocate appropriate memory on the receiver machine for these data.
• Store the start address of the allocated memory into the pointer (reference)
variable.
• Example: Chained list.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 64

Problem 5: non self describing data structures (especially in C)


Pointers do not contain any information on the amount of the data they point to.
Example (C programming language)

float x[100]; /* is x an array of 100 float */


/* or a pointer to float ? */
float *y /* y is a pointer to float */

"Serialise y" => serialise y, a "pointer to float" ? => Does not make sense
serialise the float to which y points? => Makes sense
serialise 100 float ? => might make sense if
there was an
instruction y=x;
somewhere before

"Serialise x" => serialise a single float ? => Does not make sense
serialise 100 float ? => Makes sense

But: in C x is nothing else than a pointer to float (the first float of the array). I.e.
in the final executable there does not exist any information on how many floats
the pointer x really points to. In other words: x looks syntactically like y.
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 65

Problem 6:
All problems 1 .. 5 have to be solved for each possible pair of different
communication endpoint technologies.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 66

Reduction of Complexity: A standardised network representation of the data

sender receiver
machine 1 data machine 2 data
representation representation

serialising deserialising
(marshalling) (unmarshalling)

network data network data


representation transport representation

standardised

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 67

• Network Data Representation (NDR)


There is a commonly agreed standard for the data representation
("date encoding scheme") on the network independent from
- programming languages,
- processors,
- hardware platforms ...
• Each programming language has to define a mapping between its internal data
structures and the NDR data elements.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 68

Network data representation in this course:

Juen Finish students

thinks think Finish


German

translation translation

English
English English
transport

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 69

NDR Examples
network data represen- Programming
Technique Explanation
tation Language
Remote Method Java object serialisation
RMI Java only
Invocation technique (name?)
Common Object Request CDR (Common Data Re-
CORBA Many
Broker Architecture presentation)
XDR (External Data Re-
ONC-RPC ... Remote Procedure Call C (Java)
presentation)
DCE-RPC ... Remote Procedure Call C++, Visual
NDR2) (Network Data Re-
Distributed Component Basic, Object
DCOM presentation)
Object Model 1) Pascal (Delphi)
Simple Object Access
SOAP SOAP Encoding Many
Protocol
1) Object oriented add on for DCE-RPC
2) Here the term NDR ("Network Data Representation") is the name of one of the
NDR standards.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 70

Webservice technique solution


uses Soap encoding scheme:
• network data representation is XML-style
• network data types are mainly XML-Schema data types

4.2 Serialising of Arrays


We continue with the transfer of more complex data structures (without having to
care about the serialisation/deserialisation process, which works automatically
"behind the curtain").

Service example
Receives an array of integers and returns the sum.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 71

The server
We simply extend the Calculator service with a method addArray:

[WebMethod]
public int addArray (int[] arr)
{
int sum=0;
for (int i=1;i<arr.GetLength(0);i++)
sum+=arr[i];
return sum;
}
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 72

The client
:

class Calculator
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
// The already existing test cases
:
:
int[] arr={11, 22, 33, 44};
Console.WriteLine(calculator.addArray(arr));
}
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 73

4.3 Exercise
a) Extend your FloatCalculator with a webmethod scalarProduct which
receives two arrays of float, interprets them as 2 vectors and returns the scalar
product. If the two arrays do not contain the same number of entries a
SoapException “Different lengths of the two arrays not allowed” is thrown.
The client should catch SoapException type exceptions.
b) Extend your FloatCalculator with a webmethod sumVector which
receives two arrays of float, interprets them as 2 vectors and returns the sum
vector. Exception handling is as in a).
c) Extend your FloatCalculator with a webmethod scalarProduct which
multiplies a float array by a scalar number.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 74

4.4 Serializing of a chained List


Webservice IntList: Several methods operating on a list of integers
Webmethod add Receives a list of integers and returns the sum.

“List of integers” data model: chained list (class IntNode)

IntNode

int nextNode

int nextNode

int nextNode

int null
IntNode

int nextNode int nextNode int nextNode int null

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 75

The server
<%@ WebService Language="C#" class="IntList"%>
using System.Web.Services;

A public class IntNode {


public IntNode nextNode;
public int i;
B }

[WebService(Namespace="com.juen")]
C public class IntList {
[WebMethod]
D public int add (IntNode startNode) {
int sum = 0;
E while (startNode!=null) { // while not last node
sum+=startNode.i;
startNode=startNode.nextNode; // go to next node
F }
return sum; // sum over all nodes
G }
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 76

A..B The class IntNode defines the nodes of the "chained integers list". It
contains the integer i and the reference nextNode to the next node.
D..G This is the method add of the IntList webservice. It is called with the
reference of the first (root) node of the "chained list of integers".
E..F The main loop of the add method walks through the list, adds all the
integer numbers of the nodes and stops at the last node.

The client
Remark: This example is not to demonstrate good modelling but shows only the
automated serialisation/deserialisation of a chained list.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 77

using System;
class IntListClient
{
static void Main(string[] args) {
IntNode intNode1 = new IntNode();
IntNode intNode2 = new IntNode();
IntNode intNode3 = new IntNode();
// create chained list: intNode1->intNode2->intNode3
intNode1.nextNode=intNode2;
intNode2.nextNode=intNode3;
intNode3.nextNode=null;
// fill the data into the nodes
intNode1.i=11;
intNode2.i=22;
intNode3.i=33;
// Create service proxy and call the service
IntList myIntList=new IntList();
Console.WriteLine(myIntList.add(intNode1));
}
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 78

4.5 Call by Value

C# call of a local object method


// call with parameters
localMethod(param);
• param = primitive type (int, float, string) => call by value
i.e. localMethod works with a param-copy
• param = complex type (array, object) => call by reference
i.e. localMethod works with the original param-data.

Call of a remote object method (webservice method)


// call with parameters
remoteMethod(param);
param = always call by value !!!!!!!!
(call by reference would mean: webservice has access to client side data!!)

Consequence 1:
(Complex) data can only be returned through the return value.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 79

Consequence 2:
If more than one data structure/object needs to be sent back all these data
structures/objects have to be packed into an appropriate "return"-object.
4.6 Complex return Value
Webservice IntList: (from above)
Webmethod scalarMult Receives a list of integers and s scalar returns the set
of integers with each integer multiplied by the scalar

Webmethod (server) , which assumes call by reference => does not work
public void scalarMult (IntNode startNode, int fak)
:
while (startNode!=null) { // while not last node
startNode.i=fak* startNode.i; // multiply by fak and
startNode=startNode.nextNode; // go to next node
}
:

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 80

Client (which assumes call by reference => does not work)


:
// fill the data into the nodes
intNode1.i=11;
intNode2.i=22;
intNode3.i=33;

// call the service


intList.scalarMult(intNode1, 2);

// display result
Console.WriteLine(intNode1.i); // you see 11, not 22
Console.WriteLine(intNode2.i); // you see 22, not 44
Console.WriteLine(intNode3.i); // you see 33, not 66
:

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 81

Server (which assumes call by value => works)


public IntNode mult (IntNode startNode, int fak)
:
IntNode actNode=startNode;
while (actNode!=null) { // while not last node
actNode.i=fak*actNode.i; // multiply by fak and
actNode =actNode.nextNode; // go to next node
}
return startNode;
:

Client (which assumes call by value => works)


:
// Call the service
IntNode ret= intList.scalarMult(intNode1, 2);

// display result
while (ret!=null) { // while not last node
Console.WriteLine(ret.i);
ret = ret.nextNode;
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 82

4.7 Exercise
4.7.1 The extended Finnish German translator
The Finnish German translator (Finger) methods provide two kinds of result
• Finnish or German word only
• Finnish or German word + additional English translation
Modify your Finger client such that it calls the methods ger2fin2eng and
fin2ger2eng which also deliver the English translation.
4.7.2 Simple News System
a) Develop a webservice which receives text-messages from clients and stores
them into a chained list. Each client should have access to all messages. The
service provides two methods:
public void addMessage(string messsage)
public StringCollection getMessages()
b) Extend the service with a login/logout mechanism:
public bool login(string password)
public void logout()
For simplicity we use only one password for all, i.e. YLIVIESKA . Use session
state for tracking the "login status" of the individual clients. A client request of a
method from a) should throw an Exception, if the client is not in login-status.
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 83

Hint: use StringCollection for storing the messages:


// Example for the use of StringCollection
using System.Collections.Specialized;
:
StringCollection sc = new StringCollection();
sc.Add("Hello");
sc.Add("I am Peter");
sc.Add("Nice to meet you");
sc.Add("What shall we do today");

// output of the whole collection,version 1


for (int i=0; i<sc.Count;i++) {
Console.WriteLine(sc[i]);
}

// remove some entries


sc.RemoveAt(sc.Count-1); // remove last entry
sc.RemoveAt(0); // remove first entry

// output of the whole collection, version 2


foreach (string s in sc) {
Console.WriteLine(s);
}
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 84

Display on the screen:

Hello
I am Peter
Nice to meet you
What shall we do today
I am Peter
Nice to meet you

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 85

5 Soap Protocol
5.1 Webservice with Transport Sniffer
If we want to observe the data stream on the HTTP transport level we can
• use some network sniffer software or
• include a "sniffer" into the data stream either at server or at client side.
Currently .NET does not provide a debugging feature such as "look at the
transport" and we have to develop it by ourselves (I did it for you).

How to add client side HTTP level logfile support (calculator example)
• Load webserviceutilities.dll from juen's website and add it as
project reference.
• Add the line using Juen.WebserviceUtilities to the calculator proxy
class file Calculator.cs.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 86

• Add the bold line before each method for which you want to have logfile
support:
using Juen.WebserviceUtilities;
:
[SoapLog (Filename="c:\\tmp\\soap.log")]
public int add(int i1, int i2)
{
:
}
• Attention: each time you refresh the web reference you generate a new proxy
class where these added lines no longer exist.

How to add server side HTTP level logfile support (Calculator server example)
• Add the line using Juen.WebserviceUtilities to the class file
Calculator.cs.
• Add a similar bold line as in the client case before each method for which you
want to have logfile support.
• Copy webserviceutilities.dll into the "application-bin" directory of the
Webservice related IIS-application (see chapter 3).

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 87

5.2 The add call SOAP messages

Request-message
A <?xml version="1.0" encoding="utf-8"?>
B <soap:Envelope
C xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
D xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
E xmlns:xsd="http://www.w3.org/2001/XMLSchema">
F <soap:Body>
G <add xmlns="http://juen.com/webservices/">
H <i1>-20</i1>
I <i2>30</i2>
J </add>
K </soap:Body>
L </soap:Envelope>

A The SOAP-message is an XML-document


B..L The XML-root element of all SOAP messages is Envelope from the
namespace prefixed by soap (for which soap stands is defined in line C)

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 88

C..D Defines all the namespaces for the standard elements. Standard elements
come from the “Soap world”, line C, and from the “XML-Schema world”,
line D and E. XML-Schema elements are not used here.
F..K The Body element contains the data related to our request. An optional
Head element allows to transport meta information.
G..J The elements add, i1 and i2 are defined by our application. The
corresponding namespace has been defined in the [WebService..] line
of the webservice asmx-file.

Response-message
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<addResponse xmlns="http://juen.com/webservices/">
<addResult>10</addResult>
</addResponse>
</soap:Body>
</soap:Envelope>

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 89

5.3 The Calculator WSDL


The WSDL (Webservice Description Language) provides all information which
defines the webservice interface:
• method calls
• request messages which transport method name and parameters from the
client to the server
• response messages which transport the result back form the server to the
client
• data types used in the messages
• parameters of the used transport
• address (“webservice endpoint”) where the service is waiting for the clients

The basic WSDL structure:

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 90

<?xml version="1.0" encoding="utf-8"?>


<definitions>
Specification of all data types
<types>
:

Definition of all request or response messages


<message> one <message> element per message
:

Definition of all remote methods


<portType>
:

Binding the service to a particular protocol (typically HTTP)


<binding>
:

Definition of the "address" where the service waits for the clients
<service>
:

</definitions>

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 91

Namespaces:
<definitions
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:s0="http://juen.com/webservices/"
xmlns:soapenc="http://schemas.xmlsoap.org/
soap/encoding/"
xmlns:tm="http://microsoft.com/wsdl/
mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
targetNamespace="http://juen.com/webservices/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
:
</definitions>
The root element defines all the used namespaces.
xmlns:s="http://www.w3.org/2001/XMLSchema"
means e.g. that a subsequent element marked with a prefix s such as
<s:complexType>
are defined in the namespace
http://www.w3.org/2001/XMLSchema

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 92

Data types
<types>
<s:schema
elementFormDefault="qualified"
targetNamespace="http://juen.com/webservices/">
here comes one element per data type
</s:schema>
</types>

Mostly data types are defined as XML Schema data types.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 93

Data type for add request and add response


A <s:element name="add">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1"
name="i1" type="s:int" />
<s:element minOccurs="1" maxOccurs="1"
name="i2" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>

B <s:element name="addResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1"
name="addResult" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
A defines a data type add, which will later be used in the add request
message

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 94

B defines a data type addResponse, which will later be used in the add
response message

Definition of a request and a response message (for add method call)


A <message name="addSoapIn">
<part name="parameters" element="s0:add" />
</message>

B <message name="addSoapOut">
<part name="parameters" element="s0:addResponse" />
</message>
A defines a message addSoapIn which transports a parameter of data
type add, which has been defined in the <types> section. This
message will later be used as "request message" of the add webmethod.
B defines a message addSoapOut which transports a parameter of data
type addResponse, which has been defined in the <types> section.
This message will later be used as "response message" of the add
webmethod.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 95

The add method call


<portType name="CalculatorSoap">
A <operation name="add">
<documentation>Adds two numbers</documentation>
B <input message="s0:addSoapIn" />
C <output message="s0:addSoapOut" />
</operation>
</portType>
A defines the webmethod add and refers it to a request message B and a
response message C.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 96

Binding the Calculator service to the HTTP-protocol


<binding name="CalculatorSoap" type="s0:CalculatorSoap">
<soap:binding
A transport="http://schemas.xmlsoap.org/soap/http"
style="document"
/>

B <operation name="add">
<soap:operation
soapAction="http://juen.com/webservices/add"
style="document"
/>
<input><soap:body use="literal" /></input>
<output><soap:body use="literal" /></output>
</operation>

</binding>
A specifies HTTP as transport layer.
B specifies transport specific details for each webmethod.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 97

The service endpoint


<service name="Calculator">
<documentation>Adds two numbers</documentation>
<port name="CalculatorSoap"
binding="s0:CalculatorSoap">
A <soap:address location= "http://localhost/
B asp.net/webservices/Calculator.asmx"
/>
</port>
</service>
Here the webservice endpoint is defined. In case of HTTP transport it is simply
the URL.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 98

Overview of the WSDL-"contract"

Web Service
has has has

endpoint transport method list


<service> <binding> <portType>
has many

method
<operation>
refers to refers to

request response
<bold> message message
means top level element <message> <message>
>refers to > refers to
Defined in request data response data
<types> type type
<element> <element>
> >
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 99

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 100

6 Asynchronous Webservice
6.1 Blocking vs. non Blocking Call

Blocking call (Calculator example)

client server

add_request

blocking call process


sum=add(10,20) add(10,20)
add_response

process the
result

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 101

Non blocking call (Calculator example)


Client Server

add_request
non blocking call
Beginadd(10,20)
process
add(10,20)

add_response
do s.th. useful
Get result:
sum=Endadd

call back method to be provided by the


client program:
processes the response synchronously
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 102

We go back to the simple calculator with method add and look into three methods
of the generated client side proxy class Calculator.

Blocking webservice call


public int add (int i1, int i2)

Non blocking webservice call


public System.IAsyncResult Beginadd (int i1, int i2,
System.AsyncCallback callback, object asyncState)
• It has the calling parameter signature int i1, int i2 of the blocking
webservice call.
• It has the name BeginWebMethod with the name WebMethod of the
blocking webservice call.
• It has to provide a callback method callback which will be called
automatically by the webservice proxy when the result has been arrived.
• It returns immediately after the webservice call has been initiated.
• asyncstate can be used to transport an arbitrary object via this call to the
callback method (see below)
• IAsyncResult, AsyncCallback are from Namepace System.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 103

Non blocking webservice result provider


public int Endadd (System.IAsyncResult asyncResult)
• It has the return value public int of the blocking webservice call.
• It has the name EndWebMethod with the name WebMethod of the blocking
webservice call.
• It is used in the callback method (see Beginadd) in order to get the return
value from the webservice proxy (after the return value has arrived).

Overview of the naming standards:


Non blocking call "result provider"

public int Endadd (IAsyncResult asyncResult)

Blocking call public int add (int i1, int i2)

public IAsyncResult Beginadd (int i1, int i2,


AsyncCallback callback, object asyncState)
Non blocking call

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 104

6.2 Calculator with non blocking add call

The non blocking client


using System;
using System.Web.Services;
using System.Web.Services.Protocols;
using CalculatorClientWithCallback.RemoteCalculator;

namespace CalculatorClientWithCallback
{
public class Program {
bool cont=true; // loop while cont ==true
Calculator calculator; // the service proxy

// "main" method
void run() ..

// asynchronous webservice callback method


public void displayResult(IAsyncResult ar) ..

static void Main() { new Program().run(); }


}
}
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 105

// "main" method
void run()
{
calculator = new Calculator();
// asynchronous call
A calculator.BeginaddWithDelay(
10, 20, // numbers to add
B new AsyncCallback(showResult), // wrapped callback
C null // object feed through not used here
);
int counter=0; // "while loop" counter
D while (cont)
Console.WriteLine("Counter = "+counter++);
}

// asynchronous webservice callback method


E public void showResult(IAsyncResult ar)
{
F int result=calculator.EndaddWithDelay(ar);
Console.WriteLine("The result is "+ result);
cont=false;
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 106

A BeginWebMethod is the convention for the asynchronous call of the


originally blocking webservice method WebMethod.
B The 3rd parameter of the non blocking webservice call contains the
callback routine (arbitrary name) which will be called by the calculator
proxy after it has received the return value from the remote service. Its
signature is
public void callback(IAsyncResult ar), line E, It cannot be
entered directly but has to be "wrapped" as AsyncCallback reference
type.
C The 4th parameter is not used in our application. It generally offers the
possibility to take a reference to an arbitrary object, which has to be
passed from the Beginadd to the Endadd method where it could be
addressed as ar.AsyncState.
This technique can be used in 2 scenarios:
- Pass local objects from call to callback, example:
Instead of using a globally known object member variable calculator we
could use a local calculator (created in run) and pass the reference of
this local calculator to the callback method.
- Relate callback to corresponding call:
In case of more than one pending requests ar.AsyncState could

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 107

transport some identifiying code to the callback method in order to relate


the callback to the corresponding call.
D This loop is to demonstrate the non blocking feature of the call in line A.
While the webservice request is pending, our program does not wait
(blocking) but does something else.
E This is the callback method. Via the IAsyncResult type variable ar
the calling webservice proxy provides some kind of reference to the
corresponding result object which has simply to be passed to the
EndWebMethod call in line F. Furthermore, it carries some additional
information, which can be used in "sophisticated" webservice applications.
F If the webservice return value is needed within the callback method (which
would be the normal case) it has to be get by this call of signature
EndWebMethod (IAsyncResult ar).

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 108

Time consuming calculator webservice


Non blocking calls only make sense for time consuming services. In order to make
the add service a little bit more time consuming we introduce a 10 s time delay into
the add method:

using System.Threading;

:
public class Calculator
{
[WebMethod (Description="Adds two numbers")]
public int add (int i1, int i2)
{
// 10 s delay
Thread.Sleep(new System.TimeSpan(100000000));
return i1+i2;
}
:
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 109

6.3 Exercise
Develop a webservice which fetches the content of a remote text file. Develop a
GUI-client which calls this service asynchronously and uses the callback method to
store the received data to the local file system. The name of the remote file and the
full path name where to store it are entered on the screen. Try to use the object
pass through mechanism to transport the local filename to the callback routine.
Remark: The following example shows a program which writes the content of a text
file to the screen.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 110

// demo: write a text file to console


using System;
using System.IO;

class TextFileDemo {

static void Main(string[] args){


FileStream fs=null;

try {
fs = new FileStream
(@"c:\tmp\test.txt",FileMode.Open,FileAccess.Read);
StreamReader sr = new StreamReader(fs);
string content = sr.ReadToEnd();
Console.Write(content);
fs.Close();
}
catch (Exception e) {
Console.WriteLine("Cannot read from file "+ file);
}
}
}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 111

7 Architectures
7.1 Software Interface for Web Site

Architecture:

webservice webservice webserver with


client dynamic interactive
"translator"
web-content

Internet

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 112

Example Finnish-German translator:


public class TwoStrings{
public string english; // English translation
public string translation; // German or Finnish
}
:
[WebMethod (Description=" Finnish -> German/English")]
public TwoStrings fin2ger2eng(string toTranslate)
{
return translate(toTranslate,"fin","ger");
}

public TwoStrings translate


(string toTranslate, string from, string to)
{
TwoStrings ret=new TwoStrings();

NameValueCollection postValues =
new NameValueCollection(6);
postValues.Add("from", from);
postValues.Add("to", to);
postValues.Add("keyb", "non");
postValues.Add("text", toTranslate);
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 113

postValues.Add("Submit.x", "47");
postValues.Add("Submit.y", "13");

WebClient webClient = new WebClient();

string uristring=
"http://www.tranexp.com:2000/Translate/result.shtml";
byte[] bodyData = webClient.UploadValues
(uristring, "POST", postValues);

string s = Encoding.Default.GetString(bodyData);
if (s.IndexOf("Could not open")>0)
{
ret.translation=
"Dictionary temporarily not available";
ret.english="";
return ret;
}

// Compile the regular expression.


// the match looks like
// {{house||hankkia asunto||majoittaa}}

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 114

Regex r = new Regex


(@"\{\{[^\}]+\}\}", RegexOptions.IgnoreCase);

// Match regular expr pattern against a text string.


Match m = r.Match(s);

// if there is a match => we found the translation


if (m.Success) {
string tmp=m.ToString(); // the matching text
int n=tmp.IndexOf("||"); // we want to seperate the
// english translation
ret.english=tmp.Substring(2,n-2);
tmp=tmp.Substring(n+2,tmp.Length-4-n);
ret.translation=tmp.Replace("||",", ");
// willi||theo||clara -> willi, theo, clara
return ret;
}
else {
ret.translation=
"Translation for '"+toTranslate+"' not available";
ret.english="";
return ret; // match failed
}
}
Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006
Webservices with C# 115

7.2 Communication across different Platforms

Example:
The SMS-service -> Java Axis

7.3 News Provider


Interactive Web-portal contains information (news) which is fetched from news-
providers which offer their "service" via webservice technique.

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006


Webservices with C# 116

webportal
"My City" own
content

web browser webservice

weather report

web browser webservice


Internet
sport news provider

webservice

local news provider

Prof. Dr. Gerhard Juen, FB Elektrotechnik Bocholt, FH Gelsenkirchen webservice.doc - 31.01.2006

Das könnte Ihnen auch gefallen