Content by Category
.NET 1.x
.NET 2.0
.NET 3.0
.NET 3.5
.NET 4.0
.NET 4.5
.NET Assemblies
.NET Framework
.NET Getting Started
Accessibility
ADO.NET
Advertorials
Agile Development
AJAX
Amazon Web Services
Analysis Services
Android
Architecture
Arduino
ASP .NET Web API
ASP.NET
ASP.NET MVC
ASP.NET WebForms
Azure
B2B (Business Integration)
BDD
Big Data
Bing
BizTalk
Book Excerpts
Build and Deploy
Business Intelligence
C#
C++
ClickOnce
Cloud Computing
Code Contracts
CODE Framework Info - non Technical
CODE on the Road!
COM+
Community
Conferences
Continuous Integration
Crystal Reports
CSLA.NET
CSS
Data
Debugger
Design Patterns
Development Process
Display Technologies
Distributed Computing
Document Database
DotNetNuke
DSL
Dynamic Languages
Dynamic Programming
Editorials
Enterprise Services ("COM+")
Entity Framework
Events
Expression Blend
F#
Fox to Fox
Frameworks
Functional Programming
Git
Graphics
HTML 5
Internet Explorer 8.0
Interviews
IOS
iPhone
Iron Ruby
Java
Java Script
JavaScript
jQuery
JSON
Lightswitch
LINQ
Linux
LUA
Mac OS X
MDX
Messaging
Metro
Microsoft Application Blocks
Microsoft Business Rules Framework
Microsoft Dynamics
Microsoft Expression
Microsoft Office
Mobile Development
Mobile PC
Mono
MsBuild
MVVM
MySQL
Network
NHibernate
node.js
NOSQL
Nuget
Object Oriented Development
Objective C
Odata
OLAP
Open Source
Opinion
Opinions
Oracle
ORM
Other Languages
Parallel Programming
Patterns
PHP
Podcasts
Post Mortem
PowerPoint
Print/Output
Prism
Product News
Product Reviews
Project Management
Prolog
Python
Q&A
Rails
Rake
Razor
Reporting Services
REST
RIA Services
Ruby
Ruby on Rails
Scheme
Search
Security
Services
SharePoint
SignalR
Silverlight
SOA
Social Networks
Software & Law
Software Business
Source Control
Speech-Enabled Applications
SQL Server
SQL Server 2000
SQL Server 2005
SQL Server 2008
SQL Server 2012
SQL Server CE/AnyWhere/Mobile/Compact
SSIS
Subversion
Sync Framework
Tablet PC
TDD
Team System
Techniques
Testing and Quality Control
TFS
Tips
TypeScript
UI Design
UML
User Groups
VB Script
VB.NET
Version Control
VFP and .NET
VFP and SQL Server
Virtual Earth
Vista
Visual Basic
Visual Basic 6 (and older)
Visual FoxPro
Visual Studio .NET
Visual Studio 11
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio 2011
Visual Studio 2012
Visual Studio Tools for Office
VSX
WCF
Web Development (general)
Web Services
WebMatrix
WF
Whitepapers
Windows 7
Windows 8
Windows Azure
Windows Live
Windows Phone 7
Windows Phone SDK
Windows Server
Windows Vista
WinForms
WinRT
Workflow
WPF
XAML
Xiine Documentation
XML
XNA
XSLT



LearnNow


XAMALOT
 


SSWUG

Reader rating:
Click here to read 4 comments about this article.
Article source: CoDe (2005 - Jul/Aug)


Article Pages: < Previous - 1 2  3  4 5 - Next >


Introducing Contract First (Cont.)

Tool Approach to Contract-First

Although tools already exist in the .NET Framework SDK that help you to generate ASMX Web service code from XSD and WSDL, they are not sufficient for effective contract-first work. Developers really need a good WSDL editor or even designer. For the XSD-related part of modeling data and messages you might want to rely on Visual Studio .NET's intrinsic XSD editor.

Let me tell you about a small tool called WSCF (Web services Contract-First) which solves a lot of the problems related to Web services, and it makes the contract-first approach to Web services easier. WSCF is primarily an add-in for Visual Studio .NET, but it also includes a command-line tool. It was designed to make implementing the above-outlined five steps of contract-first Web services as easy and smooth as possible. Therefore, WSCF has two main responsibilities: aid in the design of the data, message and service interface contract description in an interoperable fashion; and generate code from a given service interface description. You'll see how to accomplish this.

In order to get a better impression of what things actually look like and see how they work, I'll walk you through a simple example. Suppose that you're a member of a .NET user group, and you want to make some of the group's member data available to the outside world. You've decided to create a Web service that delivers and accepts data packed in SOAP messages and a client application that talks to this Web service.

Web Service Interface Design in Practice

Your first want to model the metadata for your Web service's interface. You'll design your data and messages with XML Schema and you'll use Visual Studio's XML editor. You'll set up an initial project structure for your Visual Studio .NET solution. You'll name the empty solution UserGroupService and you'll add the projects to it in order to complete the sample.

The first project (named ContractMetadata) is an empty C# project that will just hold all of the original XML metadata files. The second project is a Windows Forms application that implements the Web service consumer (called UGClient). Last but not least, you'll create an empty ASP.NET Web project. This project will be the home of your user group Web service, but you'll start with an empty project. Please refer to Figure 3 to see the initial solution setup.

Click for a larger version of this image.

Figure 3: VS.NET sample solution.

Data and Message Contract

In the very first step you need to start modeling the data that you'll use in the service interface. You'll model the data in XML Schema and in this case it consists of simple and complex types. For the purpose of an integrated development experience you'll stay completely inside the Visual Studio .NET IDE and therefore use its intrinsic XSD editor. Listing 1 shows UgData.xsd, the file that contains the data. You can see one simple and two complex schema types in there. The enumeration DotnetExperience is the simple type, whereas the "structs" UgMember and UgMemberlist represent complex types. For those of you who are not too familiar with XML and XSD: imagine those data structures as an XML-ized variant of Fowler's data transfer objects (DTO).

Next you want to define the messages that you'll exchange through the service interface. Those messages will re-use the data structures modeled in the first step. So technically, this means that your schema file UgMessages.xsd needs an xsd:import statement for the UgData.xsd file.

<xs:import schemaLocation="UGData.xsd" 
id="ugData" namespace="urn:thinktecture
com:demos:usergroup:data:v1" />

This simple line imports a certain XML namespace into the current document which makes all data types available inside the message schema definition file.

This example uses three messages: RegisterMemberMessage, GetMemberDataRequest, and GetMemberDataResponse (Listing 2). Those messages are just loosely placed inside the schema file and do not yet have any correlation amongst them. If you like, they are just raw messages.

Interface Contract

In the third step you'll have to design the actual service interface with its operations. This means you need to map the single messages to operations inside an interface. This phase is obviously the most tedious to complete. Here you won't just use XSD, but rather the quite complex WSDL dialect. Whereas tool support for XSD is extremely good for .NET developers, I haven't found good WSDL editors or designers. This is one of the major reasons why I started to develop and distribute the free WSCF tool. WSCF has a WSDL Wizard component to design the service interface contract of a Web service, as well as enhanced code generation features. Let me now walk you through how to use WSCF to create a WSDL description without having to grok every single detail of this specification or to even handcraft WSDL in Notepad.

In order to get started using the WSDL Wizard you need to add the two existing XSD files for the data and the message types to your contract metadata project. Based on the messages you have designed, you now want to set up the interface. You just have to right-click on the UgMessages.xsd inside your Visual Studio .NET project and select Create WSDL Interface Description... from the context menu (see Figure 4). The WSCF WSDL Wizard opens with a welcome page. On the following page the user has to provide some basic information about the interface including the name, XML namespace and an optional comment. The next page in the wizard allows you to add additional message XML Schema files. Because sometimes you can start right away with one file, but actually have different kinds of message types distributed across several XSD files (see Figure 5).

Click for a larger version of this image.

Figure 4: Starting the WSDL Wizard from a message XSD.

Click for a larger version of this image.

Figure 5: Specifying message schema imports.

Now on to the real meat. Page three of the WSDL Wizard offers a listview component that allows you to add the interface's operations. For your user group scenario you decide to specify two operations named GetMemberData and RegisterNewMember. But this is not enough information to complete this step. There needs to be an explicit configuration of the message exchange pattern (MEP) to employ for each operation. Currently, there are two possible values for the MEP: One-Way and Request/Response. The former expresses that this is a one-shot action, which means you do not want any message sent back to the original sender. The latter indicates that there has to be an answer to the request message (Figure 6). If you are following certain naming patterns for the modeled messages, the wizard will be able to infer the operations from the messages. Just like GetMemberDataRequest and GetMemberDataResponse will result in the GetMemberData operation when using inference.

Click for a larger version of this image.

Figure 6: Declaring the Web service's operations - with operation inference.

You're nearly done. The last important step lets you specify the operation's message parameters. On this page the user simply needs to map the appropriate message from the message XSD files to the message part of each operation. If you were using operation inference in the previous step the wizard has already set the right values here. Optionally, you can also set any number of message headers on this wizard page. Message headers accord to SOAP headers and you can use them to communicate out-of-band data and information like security credentials or transaction IDs (Figure 7). Although there are still some options on the last page of the wizard, you normally do not need them. That's it! Now you should have all the necessary data to actually get the service interface description generated by the tool. When you finish the wizard you have a newly added WSDL file called DotnetUserGroupWebService.wsdl in your project (Figure 8).

Click for a larger version of this image.

Figure 7: Configuring message body and headers.

Click for a larger version of this image.

Figure 8: Generated WSDL in the metadata project.

Design Patterns

Speaking of the WSDL, WSCF tries to follow the best practices and rules from the WS-I Basic Profile 1.1. For example, it only generates Document/literal style WSDL and creates one portType per service description (Table 2 lists the features supplied by the wizard). A more thorough look at the generated WSDL (Listing 3) unearths a small but very powerful implementation detail. The message schemas are not embedded in the WSDL but rather just imported.

<types>
  <xsd:schema>
    <xsd:import schemaLocation="UGMessages.xsd" 
namespace="urn:thinktecture-
com:demos:usergroup:messages:v1" />
  </xsd:schema>
</types>

This approach has several advantages. The most obvious one is reusability and the second most obvious is that it lets you independently work on the message schemas and the interface contract. So you can easily use or re-use already existing schema for your service's messages.

All in all this makes three important metadata files. Both the Web service implementer as well as the client programmer will now need to receive the UGData.xsd, UGMessages.xsd and DotnetUserGroupWebService.wsdl files in order to start their work. You can add all three files to the respective projects for the Web service and the Windows Forms client application. Now you can head into the code generation process.

&


Table 2: WSCF WSDL Wizard's WSDL generation features.
FeatureDescription
Operation inferenceThe wizard can infer operations from existing message schema. Based on string pattern matching.
WS-I BP conformanceGenerated WSDL conforms to the best practices and rules of the WS-I's Basic Profile.
Round-trippingExisting WSDL files can be edited in the WSDL Wizard.
Multiple XSD importsMultiple XML Schema message files can be added to a service interface description.


Listing 1: UgData.xsd - User group data schema
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="UGData" targetNamespace=
 "urn:thinktecture-com:demos:usergroup:data:v1"
 elementFormDefault="qualified"
 xmlns="urn:thinktecture-com:demos:usergroup:data:v1"
 xmlns:mstns="urn:thinktecture-com:demos:usergroup:data:v1"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="DotnetExperience">
    <xs:restriction base="xs:string">
      <xs:enumeration value="WhatIsDotnet" />
      <xs:enumeration value="None" />
      <xs:enumeration value="ICanHitF1" />
      <xs:enumeration value="GoogleRocks" />
      <xs:enumeration value="CallMeGod" />
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="UgMember">
    <xs:sequence>
      <xs:element name="Firstname" type="xs:string" />
      <xs:element name="Name" type="xs:string" />
      <xs:element name="Birthday" type="xs:dateTime" />
      <xs:element name="Experience" type="DotnetExperience" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="UgMemberList">
    <xs:sequence>
      <xs:element name="Member" maxOccurs="unbounded" minOccurs="0"
        type="UgMember" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>


Listing 2: UGMessages.xsd ? User group Web service messages schema
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="UGMessages" targetNamespace=
 "urn:thinktecture-com:demos:usergroup:messages:v1"
 elementFormDefault="qualified" 
 xmlns="urn:thinktecture-com:demos:usergroup:messages:v1"
 xmlns:mstns="urn:thinktecture-com:demos:usergroup:messages:v1"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:dataimport="urn:thinktecture-com:demos:usergroup:data:v1">
  <xs:import schemaLocation="UGData.xsd" id="ugData"
   namespace="urn:thinktecture-com:demos:usergroup:data:v1" />
  <xs:element name="RegisterMemberMessage">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="MemberData" type="dataimport:UgMember" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="GetMemberDataRequest">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="MemberID" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="GetMemberDataResponse">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="MemberInfo" type="dataimport:UgMember" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="GetAllMembersRequest">
    <xs:complexType>
      <xs:sequence />
    </xs:complexType>
  </xs:element>
  <xs:element name="GetAllMembersResponse">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Members"
         type="dataimport:UgMemberList" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>


Listing 3: Generated WSDL for user group Web service
<definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="urn:thinktecture-com:demos:usergroup:webservice:v1" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/
xmlns:import1="urn:thinktecture-com:demos:usergroup:messages:v1" 
targetNamespace=
"urn:thinktecture-com:demos:usergroup:webservice:v1" 
name="DotnetUserGroupWebService" 
xmlns="http://schemas.xmlsoap.org/wsdl/">
<documentation>This is the entry point into the .NET User Group
service application.</documentation>
  <types>
    <xsd:schema>
      <xsd:import schemaLocation="UGMessages.xsd"
       namespace=
       "urn:thinktecture-com:demos:usergroup:messages:v1" />
    </xsd:schema>
  </types>
  <message name="GetMemberDataIn">
    <part name="messagePart" 
     element="import1:GetMemberDataRequest" />
  </message>
  <message name="GetMemberDataOut">
    <part name="messagePart" 
     element="import1:GetMemberDataResponse" />
  </message>
  <message name="RegisterNewMemberIn">
    <part name="messagePart" 
     element="import1:RegisterMemberMessage" />
  </message>
  <portType name="DotnetUserGroupWebServiceInterface">
    <documentation>This is the entry point into the 
     .NET User Group service application.</documentation>
    <operation name="GetMemberData">
      <input message="tns:GetMemberDataIn" />
      <output message="tns:GetMemberDataOut" />
    </operation>
    <operation name="RegisterNewMember">
      <input message="tns:RegisterNewMemberIn" />
    </operation>
  </portType>
<binding name="DotnetUserGroupWebService" 
 type="tns:DotnetUserGroupWebServiceInterface">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
     style="document" />
    <operation name="GetMemberData">
      <soap:operation soapAction=
       "urn:thinktecture-com:demos:usergroup:webservice:v1:
        GetMemberData" style="document" />
      <input>
        <soap:body use="literal" />
      </input>
      <output>
        <soap:body use="literal" />
      </output>
    </operation>
    <operation name="RegisterNewMember">
      <soap:operation soapAction=
       "urn:thinktecture-com:demos:usergroup:webservice:v1:
        RegisterNewMember" style="document" />
      <input>
        <soap:body use="literal" />
      </input>
    </operation>
  </binding>
</definitions>


Article Pages: < Previous - 1 2  3  4 5 - Next Page: 'Generating Code' >>

Page 1: Introducing Contract First
Page 2: Web Services
Page 3: Tool Approach to Contract-First
Page 4: Generating Code
Page 5: Creating Client Code

How would you rate the quality of this article?
1 2 3 4 5
Poor      Outstanding

Tell us why you rated the content this way. (optional)

Average rating:
4.0 out of 5

78 people have rated this article.

Instantly Search Terabytes Of Text
“Lightning Fast”
– Redmond Mag
“Covers all data
sources” – eWeek
25+ fielded & full-text search options
dtSearch’s own document filters highlight hits in popular file types
Web Spider supports static & dynamic data
APIs for .NET, Java, C++, SQL, etc.
Win / Linux (64-bit & 32-bit)
www.dtSearch.com
 

      LearnNow

 

SSWUG