Quiz for WCF software developers
What is a data contract?
A Data contract defines \ formalizes the message structure required by the WCF service operation to function.
Why do we need the concept of data contracts? Why can’t a service operation not just return the .net Type?
Because WCF services do not expose the implementation technology.Why?To be technology neutral. It is technology agnostic. Returning the .net type the client would need to be able to read and understand the type and that means knowing the language on the other side.By being technology neutral the client and the server-side processes does not need to be written in the same technology (Language) or by the same people.
Statement – To define a class as data contract the attribute DataContract can be added above the class name in .NET
Can a .net class that is not marked as a data contract be used and returned with a service operation;
Yes, however this will result in a inferred data contract where the data contract is generated for you from the public members of the class.You are not advised to this as it is considered bad practise.Inferred contracts do not support versioning – All their members will be required to be present during the serialization and de-serialization.
Does marking a class with the attribute [DataContract] automatically include all the members of the class when it is being sent over the service layer?
No, each member needs to be opt – in by itself.
If you notice that you are not getting any data on the server or client side from a data contract but you know it was sent then chances are good that the [DataMember] attribute was left off for that member.
Are there any exceptions to this? Yes – Inferred data contracts. Inferred data contracts are normal CLR types converted automatically to data contracts. Inferred data contracts have no support for versioning and are considered a hack as it breaks the standard of Opt-in.
Statement – The attribute Data Member must be added to all members that you wish to expose on the data contract.
What types can be used as data members.
Only primitives or other data contracts. WCF offers implicit data contracts for all primitive types as an industry standard. This includes Byte, SByte, Int16, Int32, Int64, UInt16, UInt32, UInt64, Single, Double, Boolean, Char, Decimal, Object, and String.
Are there any special types that .Net serializes for you as if they where primitives? Yes, DateTime, DateTimeOffset, TimeSpan, Guid, Uri, XmlQualifiedName, and arrays of Byte.
Statement – When using inheritance with data contracts only members marked as data members by the base will be exposed by the inherited data contract.
Statement – Data members on data contracts are always in alphabetical order within the metadata unless specified otherwise with the order attribute.
Does the access modifier (visibility) like public, protected, internal and private on a data member member affect the data contract?
No, it doesn’t. Adoring even a private member with the attribute of data member will expose it via the data contract.
Is it possible to receive a DataContract with less or more data members on it than what you expect.
Yes, WCF data contracts are designed to be flexible in this way. Only data members marked as “IsRequired” are required to be present on the data contract.
Does marking a data member as “IsRequired” force a client or server to provide it with data?
No, the flag “isRequired” on a data member ensures safety but limits versioning. It stipulates only that a data member with the specified name must always be present on a data contract.
How is the data contract type information represented over the service boundaries so that the clients know what they are getting and need to send?
The data contracts are published as metadata in XML format by the service. The clients can access this to find the supported message structures.
When a data contract message is send over the service layer – what is actually being sent?
Only the structure of the contract and the state of the data. There is no type information present.
Polymorphism is not supported with WCF. When passing a derived data contract into an operation instead of the expected type you will get an exception. Why?
The reason is cause you are not working with a reference types and instead with object state that is being matched on the member signature. WCF can’t match the derived type to the expected type and thus does not know what to do with the extra data.
The way to get around this is to use known types and tell WCF about the accepted data contract types that can act as substitutions for a specific data contract. WCF will then at runtime check the incoming member signatures (Data members) and match them to the known types to identify the type that it has received.
How can i work with data contracts that have been inherited from a base type without specifying the known type?
To resolve data contract types dynamically instead of using the knowntypes features you can implement a DataContractResolver that intercepts the serialize and de-serialize method to allow you to at runtime try and determine the type of data contract.
Data Contracts provide 4 events pertaining to the serialization and de-serialization of a contract. This becomes useful during versioning on data contracts. What are they?
Does WCF implement versioning on data contracts?
Officially Microsoft states: “Windows Communication Foundation (WCF) does not have any versioning support, other than the fact that elements are marked as optional by default”
How does WCF handle different versions of data contracts then?
WCF is version tolerant it does not have specific version support. It will adjust the data contracts according to what the client and service is expecting.
Is there any way to know what “version” of a data contract you will be working with or can expect?
The namespace property on the data contract is used for visioning. By specifying the namespace on the data contract the client will know what to work with for the current service.
What do i need to when altering an existing data contract? How do i take care of versioning?
After a data contract has gone live in a production environment it should not be altered. During development phase it can be altered.
The way to get way from altering existing contracts is to create a new Data Contract or inherit from the existing one and specify a new namespace on the new data contract. It is best to try and not inherit but to define a unique data contract every time.
Statement – WCF allows the client and service to have different versions of a contract.The client and service can even remove some of the non-required data members before serialization; which mean the members will not be present when the data contract is de-serialized.
When running multiple “versions’ of data contracts the service will always support the data contract with the most members.
Because a client can be using an older version of a data contract some of the non-required members could be missing or left off.
The Data contract serializer will automatically default missing member to have either a 0 or nil value during deserialization.
To prevent faults the OnDeserializing event on the data contract can be used to provide missing members with other default values.
Now what if a newer version of a contract has a new member and that member is marked as required and the client is running an older version?
At this point the IsRequired flag on the new data contract will be turned off automatically and a check will not be done on the member.The IsRequired flag is only enforced if the server and client are running on the same version of the data contract.
Statement – In a situation where you wish to make data contracts compatible with future unknown changes the IExtensibleDataObject interface can be implemented on the data contract.
How is the IExtensibleDataObject used?
Follow this example; a Service supports the latest data contract (Ver 2) while a client supports (Ver 1).The client receives Ver 2 of the data contract from the services and passes the data contract received to a 3rd service that supporting V2 but the client only support version 1.
In this situation data could go missing. The IExtendibleDataObject interface provides a data field in which the extra information can be stored – to not lose it.
The IExtensibleDataObject is automatically implemented on data contracts when it is generated from metadata by visual studio 2010 even if the original data contract did not implement it.
If you don’t generate data contracts from metadata you need to implement the interface yourself. As a developer you don’t need to interact with IExtensibleDataObject interface at any point after it has been implemented.
When will you decorate an Enum with a data contract?
Only when you wish to exclude some of the enumeration values.
Statement – Generics cannot be used with WCF Data Contracts.
Statement – Collections on data contracts are defined as arrays on the data contract.The conversion from collection to array and back to collection is done automatically for you.
Programming WCF Services – Juval Lowy