Create data and message schema, design WSDL interface contract and generate
code from WSDL
by thinktecture's Christian Weyer
Last update: 1/17/2005
In this article I will show you how you can live and breath the concepts of
contract-first Web services - all inside your beloved Visual Studio .NET. The
contents of the generated WSDL and generated code files will not be shown here -
you can easily reproduce those results by following this walkthrough
step-by-step - or go with the sample
download.
Contract-First Approach
Just to make sure every reader knows about the basic concept of
contract-first Web services and all steps involved in it, I am going to quickly
recap what it means to design and develop Web services in a contract-first way.
First, there are two ways to do contract-first Web services development:
The first option uses all the XML- and WSDL-related attributes inside the .NET
Framework
However, I am a big friend of the latter approach, and therefore developed a
tool for the .NET Framework and Visual Studio .NET to easen the schema-based
approach to contract-first Web services.
But what do you exactly have to do you when following the contract-first
paradigm? There are basically four steps to watch out for:
- Model your data.
This step involves thinking about which data should be exchanged through
your Web service interface. This is an explicit view on explicit data. One
can think of it as the XML-ized way of defining data transfer objects (but
without the object ;)).
- Model your messages.
Write down which messages you will need to exchange the data you hav modeled
in the previous steps. These messages will be used in your Web service
interface later on.
- Model your operations.
Define which operations you want to offer to the Web service consumer.
Operations are made up of message exchange patterns (e.g. one-way or
request/response) and their associated messages - those messages you have
designed before, which use the data you have defined in first place.
- Generate code.
Generate your platform and programming language code as appropriate - based
on the message and interface contract defined in the previous steps.
So, after a bit of theory, we should get started and dive into the real guts.
Demo Scenario
For the puropose of this article we will take a look at a .NET user group that
wants to make some of its member data available to the outside world. There will
be a Web service that delivers and accepts data packed in SOAP messages and a
client application talking to this Web service.
Visual Studio .NET Solution
First, let's create a blank Visual Studio .NET 2003 solution. We will add
our projects to this blank solution afterwards.

Now we need to add our working projects to this solution.
In order to have all needed projects inside our solution we just add an empty
C# project for all the contract metadata (i.e. all XSDs and WSDLs). Another project
is for the Web service implementation - note we do not add a
ASP.NET Web
Service project to our solution, but rather a C# Empty Web
Project. This is
obvious, as we want to omit the automatic and template-driven code generation of
our Web services code in first place - we want to take the contract-first route.
The last project is a C# Windows Forms application to realize a simple client app
that consumes the Web service.
If all three projects are added to the solution, your Solution Explorer window
might look like the following screenshot:

Modelling the Message Contract
Now let's get ready to rumble. Our first job is to go and model the data and
the messages we want to leverage in our Web service. Therefore, we are now
concentrating on the Contract Metadata project exclusively.

According to the steps to take in contract-first design, our first step is to
create an XML Schema which resembles the data we want to use.
Please add an .xsd file called UGData.xsd to our
Contract Metadata project
(UG stands for User Group).
As you can see in the next picture we need to add some simple and complrx
types to our schema file in order to have all the data in place we need. We have
a complex type UGMember, a complex type
UGMemberList, and a simple type
DotnetExperience. I think the meaning of all data should be quite obvious by
looking at the screenshot below (please do not blame me here for not having
modeled everything real-world-like...)..
This is the data we will base our messages on. We will reference this data
file in a new file where our messages structures will live in.

Please add another .xsd file to our project and name it
UGMessages.xsd. Our
next task is to model the messages that get exchanged through our Web services
interface.
For this simple demo scenario we will have three messages:
registerMemberMessage, getMemberDataRequest, and
x. Again, I
hope that the meaning of these messages are self-explanatory - you can see alle
the completely defined messages in the next picture.
Note: in this case I use elements with embedded (anonymous) complex types for defining
the messages. Alternatively, I could also first model my complex messages types
and then 'instantiate' them by adding elements of the appropriate types.

A very important detail is that the contents of the other XSD file, our
UGData.xsd, has to be imported into
UGMessages.xsd. This way we are reusing the
data we have modeled before (alternatively, your data might already exist in
some other context, and you can just add it to your project and reference in in
the message schema). For this to happen, we simply use the
xsd:import mechanism:

Fine. The first two steps - modeling the data and the messages - seem to be
done. Now let's go on to the next big step: defining our Web service's
interface.
Modeling the Interface Contract
For this, we do not want to hand-craft our WSDL. Obviously, there are some
nice and quite usable WSDL editors out there - but we want to stay inside the
Visual Studio.NET IDE and want to have everything integrated. Additionally, it
would be very nice and comfortable to hide away all the details of WSDL (1.1)
that one really does not need to know and fight with. At last, we want our WSDL
to be totally compliant to the WS-I BP 1.0a, which means we have to deal with
some rules and guidelines.
Let's take WSCF 0.4 to create the WSDL interface description from our already
present message schemas. Simply right-click on the UGMessages.xsd file and
choose 'Create WSDL Interface Description...' from the context menu as shown
below.

The whole process of creating a WSDL for our Web service is wizard-driven.

In Step 1 we need to specify some metadata for our Web service description.
This includes the service name, the Web service's XML namespace and an
optional description.

In Step 2 we can finally add all the operations we need to our interface.
Simply click the 'Add operation' link button at the buttom of the dialog and add
operations as appropriate. For our demo we just need two operations:
GetMemberData and RegisterNewMember.
Do not forget to select the correct message exchange pattern (MEP) for your
operations. In our case, the RegisterNewMember operation is a one-way operation,
whereas the other one is a typical request/response operation.

Before we are finished, we need to map all available messages in our message
schema file to our operations. As an example, in the screenshot below we just select
registerMemberMessage from the first combobox in order to map the right message
to the in message parameter of the RegisterNewMember operation.
Optionally, we could also specify a message header, but we do not need or
want one in this case.

Final spurt... the next page of the wizard offers two additional options.
Here you can select whether you want to specify where the message schema you are
intending to use is located somewhere else, and whether you want to open the
code generation dialog right after the WSDL wizard closes.

... and finally we are done.

We now happen to see a newly generated file added to our project:
DotnetUserGroupWebService.wsdl - our Web service interface description metadata.
This and the two XSDs are all we need in order to generate code for nearly
any platform and programming language.

Code Generation from Contract
For this walkthrough, we want to focus on the .NET platform and on Visual
Studio .NET as our IDE. Thus, we now need to distribute the contract
metadata to the client and the Web service developer - as can be seen in the
next picture.

Client-side Code Generation
The client and the Web services programmers are totally independent (OK, in
our walkthrough everything is contained in one solution- but I think you get
it...).
We can start the code generation process for our client by simply
right-clicking the .wsdl file we previously created through the wizard and which
we received either by copy and pasting it from an email, from UDDI or ... you
name it. Choose 'Generate Web service Code...' and off we go with the code
generation options dialog.

Select all options as shown in the next picture. As we want to create a
client-side proxy class for our Web service consumer, so we just need to activate
this option.
All other options are actually optional. They are selected in order to show
the power of the code generation engine as it can produce much more usable and
productive .NET code than the .NET Framework's intrinsic tools
wsdl.exe and 'Add
Web Reference...' can do.

After hitting the 'Generate' button, we will see our updated client project.
Two new files are generated: App.config and
WebServiceProxy.cs

Now it is not very nice to have these two files in a sub folder (actually, the
App.config has to be at the project root level).
So please move these files to the project root and make sure your project looks
like the following:

The Web services endpoint must be configured via an entry in the
App.config
file - the Visual Studio .NET IDE reminds you of this fact by adding a new task
to the task list.

It is fine that we now have the proxy in place for the client app - so now
the client programmer can go on and implement all the nice GUI stuff and connect
the data from the Web service to its user interface process logic.
Web service-side Code Generation
In the meantime, the Web services developer already started to consume the
contact metadata he has been supplied with.
Likewise, he right-clicks on the WSDL and fires up the code generation
options dialog.

He selects 'Service-side interface' and chooses to have all the nice code
generation features applied to his Web service stub class.

For him, the IDE generates a new task item to remember the developer that the
ASMX help and documentation page has been disabled in the
web.config file. That
means you cannot test the Web service via the built-in mechanisms - and more
important: you cannot call ?WSDL on the Web service endpoint.

The following files have been generated by WSCF for a Web service project
(which originally was not a Web service project but am empty Web project).

But Visual Studio .NET hides some of the more interesting things from the
developer. To see all the files in the project click the 'Show All Files' button
right at the top of the Solution Explorer.

So we have four files in total. All we need to do here is move the generated
files web.config, WebService.cs,
WebService.asmx, and WebService.asmx.cs to
the project's root level. Done.

That's it! Schema-based contract-first Web services design and development -
for real.
All happens completely inside the Visual Studio .NET 2003 IDE - by leveraging
the existing XSD Designer and WSCF adding a WSDL wizard and code generation
options to the IDE's feature
set.