Windows Communication Foundation Top to Bottom (Part 02 of 15): Contracts

Michele Leroux Bustamante Chief Architect IDesign Inc.

About Michele Leroux Bustamante
IDesign Inc., www.idesign.net Microsoft regional director MVP – Connected Systems BEA technical director IASA - board member Published – MSDN®, CoDe, TheServerSide International speaker, International .NET Association (INETA) Program advisor, UCSD Extension Track chair, SD Expo www.dasblonde.net, www.thatindigogirl.com

What We Will Cover
How to design service contracts for your Windows® Communication Foundation (WCF) services Handling complex type serialization Working with service contracts, data contracts, and message contracts Code-first versus contract-first approaches

Session Prerequisites
Experience building Microsoft® .NET Framework applications Basic understanding of WCF clients and services

Level 100

Agenda
Contracts and metadata Service contracts Complex type serialization
Serializable types, data contracts, known types, IXmlSerializable

Message contracts Summary of approaches

Clients and Services ServiceHost Endpoint Service Endpoint Host Process .

Clients and Services Client App ServiceHost Proxy Endpoint Endpoint Service Endpoint Client Process Host Process .

Clients and Services Client App ServiceHost Proxy Endpoint Endpoint Service Endpoint Client Process Host Process .

Demonstration One Contracts and metadata .

WCF Contracts Service contracts Data contracts and other serializable types Message contracts .

IXmlSerializable Message contracts Summary of approaches . known types. data contracts.Agenda Contracts and metadata Service contracts Complex type serialization Serializable types.

} .Service Contracts ServiceContractAttribute Define service operations OperationContractAttribute Methods exposed as part of the public service contract [ServiceContract] public interface IContentManagerService { [OperationContract] void SaveLink(LinkItem item).

thatindigogirl. Namespace= "http://www.ServiceContractAttribute Applied to interfaces or classes Prefer interface Remove coupling to service implementation Services may implement >1 contract Always provide meaningful Namespace Can provide explicit Name [ServiceContract(Name="ContentManagerContract".com /samples/2007/07")] public interface IContentManagerService {…} .

thatindigogirl. } . ReplyAction="http://www.com/samples/2007/07/ ContentManagerContract/SaveLink".thatindigogirl. Action= "http://www. Action.OperationContractAttribute All methods in a service contract should have OperationContractAttribute Can provide explicit Name.com/samples/ 2007/07/ContentManagerContract/SaveLink")] void SaveLink(LinkItem item). ReplyAction [ServiceContract(Name="ContentManagerContract".thatindigogirl.com/samples/2007/07")] public interface IContentManagerService { [OperationContract(Name="SaveLink". Namespace = "http://www.

thatindigogirl. Namespace= "http://www. [OperationContract] [return: MessageParameter(Name="LinkItem")] LinkItem GetLink(string id).com/samples/2007/07")] public interface IContentManagerService { [OperationContract] void SaveLink([MessageParameter(Name="LinkItem")] LinkItem item). } .MessageParameterAttribute Use MessageParameterAttribute to control parameter or return naming [ServiceContract(Name="ContentManagerContract”.

data contracts. known types. IXmlSerializable Message contracts Summary of approaches .Agenda Contracts and metadata Service contracts Complex type serialization Serializable types.

Complex Type Serialization Serializable types Data contracts Known types IXmlSerializable .

DataContractSerializer DataContractAttribute IXmlSerializable XML DataContractSerializer SerializableAttribute XSD WSDL .

private string m_url.SerializableAttribute SerializableAttribute. private string m_description. // property accessors } . private string m_title. private DateTime m_dateStart. private DateTime m_dateEnd. Serializable Many CLR types are serializable All fields are serialized Regardless of accessibility No control over naming conventions or data types [Serializable] public class LinkItem { private long m_id.

Data Contracts DataContractAttribute Translation between CLR types and schema DataMemberAttribute Opt-in members for serialization Applied to fields or properties Preferred way for DataContractSerializer to work with complex types .

Demonstration Two Data contracts .

com/samples/2007/07")] public class LinkItem {…} .DataContractAttribute Always provide a Namespace Web service conventions use “schemas” prefix to service target namespace Can provide explicit Name [ServiceContract(Name="ContentManagerContract”. Namespace="http://www. Namespace= "http://schemas.com/samples/2007/07")] public interface IContentManagerService {…} [DataContract(Name="LinkItem”.thatindigogirl.thatindigogirl.

} set { m_id = value. IsRequired = false. Order = 0)] public long Id { get { return m_id. } } . IsRequired [DataMember(Name = "Id".DataMemberAttribute Applied to fields or properties Always provide Order Default order is alphabetical Can provide explicit Name. [DataMember(Name = "Id". IsRequired = false. Order = 0)] private long m_id.

Data Contract Schema Alphabetical Ordering (Default) <xs:complexType name="LinkItem"> <xs:sequence> <xs:element minOccurs="0" name="m_dateEnd" type="xs:dateTime" /> <xs:element minOccurs="0" name="m_dateStart" type="xs:dateTime" /> <xs:element minOccurs="0" name="m_description" nillable="true" type="xs:string" /> <xs:element minOccurs="0" name="m_id" type="xs:long" /> <xs:element minOccurs="0" name="m_title" nillable="true" type="xs:string" /> <xs:element minOccurs="0" name="m_url" nillable="true" type="xs:string" /> </xs:sequence> </xs:complexType> .

Order = 0)] public long Id {…} [DataMember(Name="Title". IsRequired = true. Order = 3)] public DateTime DateStart { get { return m_dateStart.com/samples/2007/07")] public class LinkItem { // fields [DataMember(Name="DateStart". } } [DataMember(Name="Description". IsRequired = false. IsRequired = true. Order = 1)] public string Title {…} // other properties } .Namespace= "http://schemas. } set { m_dateStart = value.[DataContract(Name="LinkItem".thatindigogirl. IsRequired = true. Order = 2)] public string Description {…} [DataMember(Name="Id".

Required Elements <xs:complexType name="LinkItem"> <xs:sequence> <xs:element name="Id" minOccurs="0" type="xs:long" /> <xs:element name="Title" nillable="true" type="xs:string" /> <xs:element name="Description" nillable="true" type="xs:string" /> <xs:element name="DateStart" type="xs:dateTime" /> <xs:element name="DateEnd" minOccurs="0" type="xs:dateTime" /> <xs:element name="Url" minOccurs="0" nillable="true" type="xs:string" /> </xs:sequence> </xs:complexType> .Data Contract Schema Explicit Ordering.

Known Types Known types enable polymorphic behavior in service contracts Expose base types in service operations Associate known types To the base types themselves To particular operations To the service contract as a whole Use declarative attributes or configuration settings .

thatindigogirl.com/samples/2007/07")] public class GigInfo: LinkItem [DataContract(Namespace = "http://schemas.thatindigogirl.com/samples/2007/07")] public class MP3Link: LinkItem .thatindigogirl.com/samples/2007/07")] [KnownType(typeof(GigInfo))] [KnownType(typeof(PhotoLink))] [KnownType(typeof(MP3Link))] public class LinkItem [DataContract(Namespace = "http://schemas.KnownTypeAttribute [DataContract(Namespace = "http://schemas.thatindigogirl.com/samples/2007/07")] public class PhotoLink: LinkItem [DataContract(Namespace = "http://schemas.

Demonstration Three Known types .

} .com/samples/2007/07")] [ServiceKnownType(typeof(GigInfo))] [ServiceKnownType(typeof(PhotoLink))] [ServiceKnownType(typeof(MP3Link))] public interface IGigManagerService { [OperationContract] void SaveLink(LinkItem item).ServiceKnownTypeAttribute [ServiceContract(Name = "GigManagerContract". [OperationContract] LinkItem GetLink(string id). Namespace = "http://www.thatindigogirl.

} . Namespace = "http://www.ServiceKnownTypeAttribute [ServiceContract(Name = "GigManagerContract".com/samples/2007/07")] public interface IGigManagerService { [OperationContract] [ServiceKnownType(typeof(GigInfo))] void SaveGig(LinkItem item).thatindigogirl. [OperationContract] [ServiceKnownType(typeof(GigInfo))] LinkItem GetGig(string id).

0. ContentTypes. ContentTypes. PublicKeyToken=null" /> </add> </declaredTypes> </dataContractSerializer> </system. Version=1. Culture=neutral.0.PhotoLink. Culture=neutral.runtime. Version=1. Culture=neutral.serialization> <dataContractSerializer> <declaredTypes> <add type="ContentTypes.0. Culture=neutral.0.<declaredTypes> <system.0.0.0. PublicKeyToken=null"> <knownType type="ContentTypes. Version=1. ContentTypes.0. PublicKeyToken=null" /> <knownType type="ContentTypes.0.runtime.MP3Link. ContentTypes. PublicKeyToken=null" /> <knownType type="ContentTypes.GigInfo.LinkItem.serialization> .0.0.0. Version=1.

Contract-First In a perfect WCF world: Create data contracts that also function as business objects Expose in service contracts In reality: May not own objects (can’t make serializable) Business object serialization may not be appropriate May need to support pre-existing schemas .Code-First vs.

IXmlSerializable IXmlSerializable types provide XSD schema to Web Services Description Language (WSDL) and metadata exchange (MEX) Contract-first support You handle mapping between XML and business objects Requires knowledge of XML Provide appropriate validation Less overhead than using interim data contracts .

WriteXml() XmlSchemaProviderAttribute Improvement on IXmlSerializable.ReadXml() IXmlSerializable.GetSchema() Return schema for WSDL and MEX .IXmlSerializable IXmlSerializable Valid in service contract (like data contract) Hook serialization process: IXmlSerializable.

Demonstration Four IXmlSerializable .

Agenda Contracts and metadata Service contracts Complex type serialization Serializable types. data contracts. known types. IXmlSerializable Message contracts Summary of approaches .

Message Contracts MessageContractAttribute Greater control over message headers and body elements Supporting attributes: MessageHeaderAttribute MessageBodyMemberAttribute Useful for: Add custom headers Control message wrapping Control signing and encryption .

ProtectionLevel=ProtectionLevel. ProtectionLevel May set explicit Name.Sign)] public class SaveLinkRequest {…} [MessageContract] public class SaveLinkResponse {…} . Namespace [MessageContract(IsWrapped=true.MessageContractAttribute Converts a type to a SOAP message Type can contain header and body elements Can set IsWrapped.

MustUnderstand . ProtectionLevel May set SOAP protocol settings: Relay.MessageHeaderAttribute Apply to fields or properties of message contract Simple technique for creating custom headers Can provide Name. Actor. Namespace.

MessageBodyMemberAttribute Apply to fields or properties of message contract Can have several body elements Equivalent to multiple parameters in operation Only way to return multiple complex types Always supply Order Can set Name. Namespace. ProtectionLevel .

} } [MessageBodyMember] public LinkItem LinkItem { get { return m_linkItem.Sign)] public class SaveEventRequest { private string m_licenseKey. } set { m_licenseKey = value. private LinkItem m_linkItem. } } } [MessageContract] public class SaveEventResponse { } . [MessageHeader(ProtectionLevel = ProtectionLevel. } set { m_linkItem = value.EncryptAndSign)] public string LicenseKey { get { return m_licenseKey.[MessageContract(IsWrapped=true. ProtectionLevel=ProtectionLevel.

thatindigogirl. Namespace="http://www. } .com/samples/2007/07")] public interface IContentManagerService { [OperationContract] SaveLinkResponse SaveLink(SaveLinkRequest message).Applying Message Contracts Message contracts are supplied as operation parameter or return value Must contain serializable members Data contracts or serializable types [ServiceContract(Name = "ContentManagerContract". [OperationContract] GetLinkResponse GetLink(GetLinkRequest message).

item). .Applying Message Contracts In the generated client proxy. custom message headers are added as parameters to operations Not optional LinkItem item = new LinkItem().SaveLink(licenseKey. m_proxy. // initialize item string licenseKey = "XXX".

LinkItem. message headers are processed as member of the message contract Message body elements also available through message contract public SaveLinkResponse SaveEvent( SaveLinkRequest message) { if (message. } .Applying Message Contracts At the service.LicenseKey != "XXX") throw new FaultException<string>("Invalid license key."). return new SaveLinkResponse(). m_linkItem = message.

data contracts.Agenda Contracts and metadata Service contracts Complex type serialization Serializable types. known types. IXmlSerializable Message contracts Summary of approaches .

WCF Contracts Summary Service contracts define available operations and signatures Data contracts and other serializable types can be included in service contract Known types enable polymorphic contracts Message contracts are useful for custom headers and other advanced requirements .

2007) Book blog: www.com .dasblonde.idesign.For More Information My blog: www.thatindigogirl.. Inc.net IDesign resources: www.net Learning WCF: A Hands-on Guide by Michele Bustamante (O'Reilly Media.

For upcoming and previously live webcasts: www.com/webcasts Got webcast content ideas? Contact us at: http://go.com/fwlink/?LinkId=41781 Today's webcast was presented using Microsoft® Office Live Meeting. Don’t forget to fill out the survey.microsoft.microsoft.com/presentlive .Questions and Answers Submit text questions using the “Ask” button. Get a free 14-day trial by visiting: www.microsoft.

Sign up to vote on this title
UsefulNot useful