Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Introducing Contract First : Page 4

Many publications and blogs consider Web services to be the silver bullet because they are so easy to implement in .NET and interoperate with disconnected systems. But are people really using Web services the way they should be used?

Generating Code
The first big phase is over. You now have your XSDs and WSDL in place. It is now time to get to the real code. You'll need to create a CLS-compliant representation of the data, message, and interface contract. Sure, you could use wsdl.exe for this task, because it is part of the .NET Framework SDK and delivers simple code generation features. But there are two major caveats: it is not fully integrated into the IDE (although there is the infamous "Add Web Reference..." dialog box) and—even more important—it does not generate good enough .NET code.

What does "good" code mean in this context? There are several factors for .NET code that gets generated from metadata. First, you should have an option that allows you to generate runtime serializable classes. Second, it is indispensable to have not just public fields in your data classes that get generated from the XSD data contract. Rather, you need a good OO style here that is reflected by having private fields and public properties. At least those two features are not present in .NET Framework 1.1. But the other strong side of WSCF provides an enhanced code generation engine that does not only fulfill these two requests. Please take a look at Table 1 for all code generation features of WSCF. A developer can choose to either use the command line tool wscf.exe or better yet use the add-in for Visual Studio .NET to smoothly stay inside their beloved development environment. For the purpose of this article I'll use the graphical add-in.

Table 1: WSCF's code generation features.




Both client-side proxy and service-side stub implement a common .NET interface that gets generated from the WSDL.


Public properties instead of just public fields can be generated for better support of data binding and a more OO-like style.

Serializable types

Generated classes can be marked [Serializable] which enables them to get processed by the run time formatters.


Array data types can be converted to .NET collections for a much richer programming model.

Multiple files

Any code artifact can be placed into its own separate file instead of generating everything into one file.


Code generation always creates message-based classes in favor of XSD-to-CLR code optimizations.

Endpoint configuration

A Web service's endpoint can be configured in a configuration file.

SOAP message access

Client side applications can access the SOAP request and response messages in a read-only manner.

SOAP message validation

Web services can leverage XML Schema validation for determining valid and invalid SOAP messages sent to the endpoint.

Figure 9: Code generation options for the Web service stub.
Creating Web Service Code
To see how code generation works with WSCF it is time to think like a Web service developer. The code generation process for the client application is analogous, because it is as simple as right-clicking on the WSDL and selecting "Generate Web service Code...." Figure 9 shows how you can select different options for code generation. You will choose all of them in order to get a fully fledged .NET representation of your data, message, and interface contract. After you've finished generating code you'll see a number of files added to the Web services project (see Figure 10). Let's take a look at each feature that WSCF provides in respect to code generation.

The first important fact to note is that WSCF exclusively works with .NET interfaces. It generates a .NET interface instead of the abstract class with all the unnecessary and duplicated ASMX attribute glue that gets spit out by tools like wsdl.exe for creating service-side stubs. This approach is extremely helpful if you want to separately host the service interface and the service implementation. For example, if you want to host the service implementation under COM+ and expose a service interface for Enterprise Services, one for WSE messaging and one for ASMX. In this case you have to define a shared interface that follows the same contract as the WSDL file. The tool also generates an interface for the consumer-side proxy if you choose to create a Web service proxy. You can imagine that this easily enables scenarios where the proxy generation and instantiation can be done by a configurable factory. By doing so you can hide the location and the chosen transport.

Figure 10: Web service project after the code generation process.
The second obvious feature is that WSCF can optionally create separate files for all data, message, and interface contract artifacts. In the sample you have files for the data types (UgMember, DotnetExperience), the message types (GetMemberDataRequest, GetMemberDataResponse, and RegisterMemberMessage), as well as for the service interface and base implementation (IDotnetUserGroup and WebService). All the types live inside the very same .NET namespace. This way a developer can easily just delete or exchange one or the other type by eliminating the file. This is sometimes useful because you might happen to have another, better implementation for example, for UgMember, in your enterprise- or project-wide types library that you would use rather than the one generated from the data contract.

If you dive into programming the Web service logic you'll discover another nice feature of the generated code. Each type has a default constructor with all necessary initialization parameters already in place. So if you want to wire up a sample implementation for the GetMemberData operation, you might proceed as in the following (please consider the completely message-oriented programming model).

// Construct response message GetMemberDataResponse resp = new GetMemberDataResponse(); // Create and fill data for response message UgMember theMember = new UgMember("Christian","Weyer", new DateTime(1974, 7, 7), DotnetExperience.GoogleRocks); resp.MemberInfo = theMember; return resp;

This makes it very easy to embrace the message-based programming model without the need to write many lines of code.

When your Web service receives a SOAP message it usually gets deserialized by the ASMX runtime with the help of XmlSerializer to build and fill the appropriate .NET objects that match the XSD-to-CLR mapping. But often this is just too much burden for the runtime to take. You might want to have the chance to validate the incoming (and also the outgoing) SOAP messages against the message and data schemas you already have in place. WSCF can optionally provide this feature for Web service implementations. When choosing this option it adds an external assembly to the project and implements a SoapExtension for handling all the schema validation logic.

Last but not least, you need an easy way to basically test your Web service. The ASMX runtime provides a documentation and help page for this purpose. But the problem with the default page is that you still might call ?wsdl on the .asmx endpoint. And this would still automatically render the WSDL inferred from the current Web service implementation, and would not use your pre-defined WSDL. WSCF takes the route of adding a new custom help page that looks and feels like the original one but disables the ?wsdl feature completely. Because in the contract-first world you start from the WSDL, you do not want to have the WSDL available through the endpoint (although it would be technically possible).

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date