TechEd day three – the first session of the day is an ASP.Net session led by Mr XML Web Services Tim Ewald.
I showed up late due to a venue change (why when they change rooms do they have to put them on the opposite sides of the mile long conference center?)
- Thinktecture’s code generator takes a WSDL contract schema and creates a framework of the application, complete with all the appropriate web services attributes. This, combined with the WSDL generator Tim was in the process of demonstrating as I walked in (CodeFirst from XMLSoap.com?), allowed Tim to create a skeleton web service without typing a single angle bracket. These third party tools enable schema first design to be less painful than in the past. Remember that when you are specifying an external contract you need to give the web service binding a name and a location. Then in the web service method attribute you need to reference that binding
- It is better to pass objects around through web services rather than passing around individual parameters. Rather than passing strings and integers to the web service methods, use an object as the only parameter in and out. This enforces the contract first design and allows for looser coupling in design. This model also makes it easier to retrieve the body of the message as XML vs multiple parameters. When specifying the service method’s ParameterStyle attribute, be sure to use the SoapParameterStyle.Bare value
- Using the XMLSerializer is a great idea as it handles marshaling. It maps instances to XML and types to XSD. It won’t process data without clear XSD mapping. Restrictions include the fasts that it only processes trees of data, it only handles public data, no duplicate references, limited support for polymorphism and limited support for collections. You’ll notice lots of XML type information in the WSDL generated attributes. This allows support for polymorphic data through the XML Serializer. To do this, you have to inform the parent type about the child type. This is the limitation of polymorphism in the XML Serializer – this is for the XML API. When designing your WSDL contract, you need to annotate your XML base types with the child types so the marshaler and the schema generator can work correctly
- Missing data – if the message doesn’t contain some expected data, the XMLSerializer uses the default value for that data type. Missing ints become equal to 0, missing strings = “”. Extra data is ignored. The XML serializer is not a schema validator – that is up to you. For optional elements, you can detect if the parameter was actually sent over the wire by checking with xyzSpecified (use the XMLIgnore attribute when defining the schema). In the 2.0 version, you can use the “?” style in the definition of the class to define the type as nullable (ex public int? Age). By using he XMLElement IsNullable=”false” attribute means that an optional piece of content which won’t be passed over the wire as nil.
- Access to XML, it is useful to bypass default marshaling and work with raw XML for schema validation, transformation and complete control over (de)serialization. This gives you the ability to make decisions on a per type basis. To work with the XML object, it is inefficient to load up a DOM object to read the XML nodes. Instead implement the IXmlSerializable interface and stream the XML with the ReadXml (XmlReader), WriteXml(XmlWriter), and GetSchema methods. GetSchema is used in 1.0 and 1.1. In 2.0 you can use an XML Schema Provider.
- WSDL.exe running from the command line avoids choices made by visual studio.net and is the only way to generate a server skeleton. This helps resolve proxy namespace issues. Helps with duplicate type issues but you have to be careful with files URIs – use the full URI on the command line eg file://
- Sharing types – the plumbing generates XSD types in service namesspaces by default. If you use the same CLR type across services, you get types in different XSD namespaces. If you generate client code for each service, you get different incompatible types in XSD. This is a problem, so you have to get around it by applying an XMLType attribute to explicitly specify an XSD namespace. This is great but can cause collisions on the WSDL type definitions. In 1.0 you have to reference the external schema (writing the contract by hand) or you could use the SoapExtensionReflector. In 2.0 you can use “wsdl.exe /sharetypes” In 2.0, you must process all the WSDLs at one time for the comparisons to work
- Using facades – data formats exposed on the wire are almost certainly not what the service or client works with internally – it’s a simplified model for easy consumption. Services and clients use the facade pattern to isolate internal details of the service from the client.
- Versioning – ASP.Net offers no intrinsic versioning model. The goal is to evolve service without breaking clients. The most common solution is to build additional endpoints. This requires mapping multiple facades to common internal models.
- WS-I basic profile 1.0. Using this you can claim conformance to the WS-I basic profile using the WebServiceBinding. This is great for interoperability.
Tim’s demos reinforced how web services are a great method for building web applications today. Great show.
— Matt Ranlett
posted with BlogJet