Monday, March 5, 2012

Defining Structural Contracts

This lesson provides you with the tools to define Data and Message contracts used by your
WCF services. When, as a service developer, you are working with .NET types that represent
the data your service works with and processes, you will use WCF Data contracts (defined in
the System.Runtime.Serialization namespace) to declare which elements of that data belong in
the structural Data contract from the consumer’s perspective as well as which of those elements
are required, which are optional, and so on.
If you need further control over what needs to appear in your messages at the SOAP header
level, or how your SOAP message structures are packaged as they are serialized out to consumers,
you can use the WCF Message contracts, defined in the System.ServiceModel namespace.
Finally, because part of your overall Data contract includes how your data is serialized at the
wire-level transport layer, this lesson provides you with the tools to gain the appropriate control
over serialization that might be required in some situations.

After this lesson, you will be able to:
􀁑 Use the DataContract attribute, along with the DataMember attribute, EnumMember
attribute, or both to define Data contracts that specify the structure of the data in
the inbound and outbound messages that your WCF service must process.
􀁑 Use the MessageContract attribute to control aspects of your messages at the SOAP
message level.
􀁑 Use collections in your Service contracts.
􀁑 Use the DataContract and MessageContract attributes, along with the IExtensible-
DataObject interface, to design version-tolerant messages and message payloads.
􀁑 Use the XmlSerializerFormat and DataContractFormat attributes to declare which
serializer WCF should use in serializing your data and to control some aspects of
that serialization.
􀁑 Use the XmlSerializerFormat attribute together with the XSD command-line tool to
build WCF services, using an XML schema-driven approach.


Data Contracts
Data contracts are the contractual agreement about the format and structure of the payload
data (that is, the SOAP body) in the messages exchanged between a service and its consumer.
They fill the .NET/WCF role that XSDs fill in the XML world.


NOTE Schema languages for XML
There are alternatives to XSDs in the world of XML: both document type definitions (DTDs) and
Relax NG are languages for declaring the structure of XML documents, but XSDs are the de facto
choice, especially in the Web services space.
Just as the purpose of an XSD is to define the structure of an XML document, the WCF Data
contract language defines the structure of data in your WCF service messages. When that data
is sent over the wire-level transport, it might be transmitted as angle-bracket-laden XML text or
it might not be. The “Controlling Serialization” section at the end of this lesson discusses this
in greater detail.
Data contracts are the preferred WCF way to enable serialization of complex types included in
operation signatures, either as parameters or as return values. Do you recall the “Real World”
sidebar at the start of this chapter? It discusses the importance of thinking of your service messages
as carrying business documents; Data contracts are the WCF mechanism for specifying
the structure of the request documents being received by your service as well as of the
response documents the service sends back to its consumers.
Consider the code that follows. To embrace the document-centric paradigm fully, always prefer
Operation contracts shown for SomeOp1 over those shown for SomeOp2:
' VB
_
Function SomeOp1( _
ByVal reqMsg As RequestMessageType) _
As ResponseMessageType
_
Function SomeOp2(ByVal element1 As String, _
ByVal element2 As String) As String
// C#
[OperationContract()]
ResponseMessageType SomeOp1(RequestMessageType reqMsg);
[OperationContract()]
string SomeOp2(string element1, string element2);
Data contracts are declared by applying the DataContractAttribute to a .NET type, and you will
need to decorate that type’s members that you want to include in the Data contract with the
DataMemberAttribute. This is an optional approach that is independent of the visibility of
members (that is, whether they have public, protected, or private visibility). Unless explicitly
declared otherwise, the new WCF serializer called the DataContractSerializer performs serialization.
In the “Controlling Serialization” section at the end of this lesson, you’ll look at how
you can specify explicitly that the earlier .NET XmlSerializer be used.
Lesson 2: Defining Structural Contracts 33
The following code shows a few Data contract definitions; first, an enumeration and then a
class:
' VB
Public Enum TitleOptions : int
_
Mr = 0
_
Ms = 1
_
Mrs = 2
_
Dr = 3
End Enum
_
Public Class ContactInfo
_
Public PhoneNumber As String
_
Public EmailAddress As String
End Class
// C#
[DataContract(
Namespace = "http://schemas.fabrikam.com/customers/")]
public enum TitleOptions : int
{
[EnumMember()]
Mr = 0,
[EnumMember()]
Ms = 1,
[EnumMember()]
Mrs = 2,
[EnumMember()]
Dr = 3,
}
[DataContract(
Namespace = "http://schemas.fabrikam.com/customers/")]
public class ContactInfo
{
[DataMember(IsRequired = false)]
public string PhoneNumber;
34 Chapter 1 Contracts
[DataMember(IsRequired = false)]
public string EmailAddress;
}
The DataContractAttribute
The DataContractAttribute, defined in the System.Runtime.Serialization namespace, is used to
declare a type as a Data contract. When using it, the essential details are as follows:
􀁑 It can be applied to enums, structs, and classes only.
􀁑 It is not inherited, so your inherited Data contracts must have the attribute applied
explicitly.
􀁑 It has only two parameters, which are covered in Table 1-3.
As with the ServiceContractAttribute, always be sure to set the Namespace property to be something
that identifies both your organization and the conceptual domain of the data and services.
The DataMemberAttribute
The DataMemberAttribute, also part of the System.Runtime.Serialization namespace, is applied
only to members and is used to declare that the member should be included in the serialization
of the data structure. This attribute provides several parameters for controlling the resulting
schema generated for a complex type, each of which is covered in Table 1-4.
Table 1-3 Named Parameter Options for the DataContractAttribute
Named Parameter Description
Name Determines the type name as it is generated in the resulting schema. The
default is the .NET type name as it is declared.
Namespace Sets the target namespace for the schema. This defaults to http://
schemas.datacontract.org/2004/07/[CLR namespace], where [CLR
namespace] is the namespace in which the complex type is defined.
Table 1-4 Named Parameter Options for the DataMemberAttribute
Named Parameter Description
Name Controls the schema element name generated for the member (that is, the
field or property) the attribute adorns. The default behavior is to use the
field or property name as defined in the .NET type.
IsRequired Controls the minOccurs attribute for the schema element. The default
value is false, that is, the element is optional, which translates into
minOccurs = 0.
Order Controls the order of each element in the schema. By default, if this property
is not set explicitly, the data members appear alphabetically, followed
by elements for which this property is set explicitly.
Lesson 2: Defining Structural Contracts 35
Here are a few points to keep in mind about the usage of these parameters when you define
your Data contracts:
􀁑 Having the EmitDefaultValue property set to false can cause problems when the IsRequired
property is set to true because the serializer might emit a default value if it doesn’t find
something it was expecting when, in fact, the correct behavior might be to throw an
exception.
􀁑 If you apply the DataMemberAttribute to both a property and a field that is associated
with calculating the property, you will generate duplicate members in the schema.
NOTE Be explicit about member optionality
Even though the default value for IsRequired is false, it is a good practice to be explicit about it in
your code by declaring IsRequired = false. That way, there is no room for doubt for a developer
managing the contract in the future.
The following additional points pertain to the ordering rules for elements in your Data contract:
􀁑 If a Data contract type is part of an inheritance hierarchy, data members of its base types
are always first in the order.
􀁑 Next in order are the current type’s data members that do not have the Order property
of the DataMemberAttribute attribute set, in alphabetical order.
􀁑 Next are any data members that have the Order property of the DataMemberAttribute
attribute set; these are ordered by the value of the Order property first and then alphabetically
if there is more than one member with a certain Order value. Order values can
be skipped.
The EnumMemberAttribute
The final Data contract–related attribute to consider is the EnumMemberAttribute. As the name
suggests, it is used to declare that a given element of an enum that has been declared with a
DataContractAttribute should be considered as part of the Data contract. The only property (or
named parameter) is the Value property, which can be used to provide an enumerated value to
be serialized. The default is its actual value within the enumeration.
EmitDefaultValue Controls whether default values will be included in the serialization. This
property is true by default, so that all data members are serialized. If this
property is set to false, any member that is set to its default value for its
type (for instance, null for reference types) will not be serialized.
Table 1-4 Named Parameter Options for the DataMemberAttribute
Named Parameter Description
36 Chapter 1 Contracts
Opt-In vs. Opt-Out
The DataContractSerializer, the new default WCF serializer, operates in an opt-in mode that is
the opposite of its predecessor, the XmlSerializer. That is, with the DataContractSerializer,
members that are to be part of the Data contract must be explicitly marked as such, whereas
with the XmlSerializer, members are assumed to be in the Data contract unless explicitly
marked as opting out. For more on working with the XmlSerializer in the context of WCF services,
see the section, “Controlling Serialization,” later in this chapter. The following code
uses the opt-out approach of the XmlSerializer to prevent the field shown in bold from being
serialized:
' VB
' The opt-out approach:
_
Public Class ContactInfo
Public PhoneNumber As String
Public EmailAddress As String
_
Public HomeAddress As String
End Class
// C#
// The opt-out approach:
[Serializable()]
public class ContactInfo
{
public string PhoneNumber;
public string EmailAddress;
[NonSerialized()]
public string HomeAddress;
}
The preceding code is very much in contrast with the following code, which uses the opt-in
approach of the DataContractSerializer. The fields shown in bold are serialized.
' VB
' The opt-in approach:
_
Public Class ContactInfo
_
Public PhoneNumber As String
_
Public EmailAddress As String
Public HomeAddress As String
End Class
// C#
Lesson 2: Defining Structural Contracts 37
// The opt-in approach:
[DataContract()]
public class ContactInfo
{
[DataMember()]
public string PhoneNumber;
[DataMember()]
public string EmailAddress;
public string HomeAddress;
}
Collections
You can use the various collection types in .NET (which means anything that implements the
IEnumerable or IEnumerable interfaces), but the specific collection-type information gets
lost in the metadata (WSDL) export, so in terms of how collection types are sent across the
wire, they all are represented as arrays. For instance, suppose you have the following contract:
' VB
_
Interface ITaskManager
_
Function GetTasksByAssignedName( _
ByVal name As String) As List(Of Task)
End Interface
// C#
[ServiceContract()]
interface ITaskManager
{
[OperationContract()]
List GetTasksByAssignedName( string name);
}
After importing the service’s metadata, a client would see the contract as follows. (Chapter 4
covers client code generation from a service’s metadata.)
' VB
_
Interface ITaskManager
_
Function GetTasksByAssignedName( _
ByVal name As String) As Task()
End Interface
// C#
[ServiceContract()]
interface ITaskManager
{
38 Chapter 1 Contracts
[OperationContract()]
Task[] GetTasksByAssignedName( string name);
}
However, there is a caveat: This happens automatically only when the collection in the contract
is a concrete collection (that is, not an interface) and is serializable (annotated with the
Serializable attribute). If that is the case, WCF can automatically serialize the collection as an
array of the collection’s type as long as the collection contains an Add operation. This holds
true for both the built-in .NET collections and for any of your own custom collections that
implement the IEnumerable or IEnumerable interface; as long as they are serializable and
have an Add operation, they can be serialized to arrays automatically.
However, what if your collection does not meet these constraints? Is there still a way to ensure
your collection serializes properly? Yes. Specify the CollectionDataContractAttribute. You can
use this attribute to annotate your own custom collections, and the resulting collection will
always be exposed to its WCF consumers as a List collection. As an example of how this
attribute is used, suppose the following is your Service contract:
' VB
_
Public Class MyCollection(Of T)
Implements IEnumerable(Of T)
Public Sub Add(ByVal item As T)
' Etc...
End Sub
Public Function GetEnumerator() _
As IEnumerator(Of T) _
Implements IEnumerable(Of T).GetEnumerator
' Etc...
End Function
Public Function GetEnumerator() _
As IEnumerator _
' Etc...
End Function
' Etc...
End Class
_
Interface ITaskManager
_
Function GetTasksByAssignedName( _
ByVal name As String) As MyCollection(Of Task)
End Interface
// C#
[CollectionDataContract(Name = "MyCollectionOf{0}")]
Lesson 2: Defining Structural Contracts 39
public class MyCollection : IEnumerable
{
public void Add(T item) { // Etc...
}
IEnumerator IEnumerable.GetEnumerator() { // Etc...
}
public IEnumerator GetEnumerator() { // Etc...
}
// Etc...
}
[ServiceContract()]
interface ITaskManager
{
[OperationContract()]
MyCollection GetTasksByAssignedName(string name);
}
After a proxy is generated on the client, it will see the return type of the GetTasksByAssigned-
Name operation as:
' VB
_
Public Class MyCollectionOfTask
Inherits List(Of Task)
End Class
// C#
[CollectionDataContract]
public class MyCollectionOfTask : List
{}
Known Types
WCF also supplies you with the KnownTypeAttribute, which enables you to designate acceptable
derived classes for a given Data contract. It can be used, for example, as shown here.
' VB
_
_
Public Class Task
' Etc...
End Class
_
Public Class LoanApprovalTask
Inherits Task
' Etc...
End Class
40 Chapter 1 Contracts
// C#
[DataContract()]
[KnownType(typeof(LoanApprovalTask))]
class Task
{ // Etc...
}
[DataContract()]
class LoanApprovalTask : Task
{ // Etc...
}
When working with polymorphic types in your Service contract, the KnownTypeAttribute is
required because polymorphism is outside the paradigm of service orientation. For example,
assume you have the following Service contract:
' VB
_
Interface ITaskManager
_
Function GetTasksByAssignedName( _
ByVal name As String) As List(Of Task)
End Interface
// C#
[ServiceContract()]
interface ITaskManager
{
[OperationContract()]
List GetTasksByAssignedName( string name);
}
If some of the objects being returned by the GetTasksByAssignedName operation are Loan-
ApprovalTask objects, the client can know how to deserialize these more specific tasks only if
the KnownTypeAttribute was used.
CAUTION Remember to think in terms of documents, not objects
The “Real World” sidebar near the start of this chapter suggests that to do service orientation well,
you will have to let go of much of your object-oriented thinking. Polymorphism is at the heart of
object-oriented thinking and really shouldn’t have much of a place in well-designed Service contracts.
Again, think “big, chunky documents” instead of objects and class hierarchies. Use the
KnownTypeAttribute with caution if at all.
Message Contracts
When developing your WCF services, Data contracts enable you to define the structure of the
data that will be sent in the body of your SOAP messages, either in the inbound (request) messages
or in the outbound (response) messages. WCF Message contracts take it one step higher,
Lesson 2: Defining Structural Contracts 41
so to speak. That is, when you use a Message contract as both the operation parameter type
and the return type, you gain control over the entire SOAP message and not just over the structure
of the data in the body. The following are the primary reasons you might want to use Message
contracts:
􀁑 To control how the SOAP message body is structured and, ultimately, how it is serialized
􀁑 To supply and access custom headers
This section covers the attributes needed to define Message contracts and the main reasons for
using Message contracts.
Message Contract Attributes
To define Message contracts, use the following attributes: MessageContractAttribute, Message-
HeaderAttribute, and MessageBodyMemberAttribute. The following sections cover each of these
individually.
The MessageContractAttribute The MessageContractAttribute can be applied to classes and
structures to define your own message structure. It has several properties, outlined in Table 1-5.
The MessageHeaderAttribute The MessageHeaderAttribute can be applied to members of a
Message contract to declare which elements belong among the message headers. It has several
properties, outlined in Table 1-6.
Table 1-5 Named Parameter Options for the MessageContractAttribute
Named Parameter Description
IsWrapped If true, the message body includes a wrapper element named by using
the Message contract type or the WrapperName if specified. If false, the
message body is unwrapped, and body elements appear directly
beneath it.
ProtectionLevel Enables the Service contract to specify constraints on how messages to
all operations in the contract are protected on the wire, that is, whether
they are signed and encrypted. See Chapter 8 for more about security.
WrapperName Supplies a custom name for the body wrapper element.
WrapperNamespace Supplies a namespace for the body wrapper element.
Table 1-6 Named Parameter Options for the MessageHeaderAttribute
Named Parameter Description
Name Controls the name of the serialized header element.
Namespace Supplies a namespace for the header element and its children unless
otherwise overridden at the type level.
42 Chapter 1 Contracts
The MessageBodyMemberAttribute The MessageBodyMemberAttribute can be applied to
members of your Message contracts to declare which elements belong within the message
body. Recall that if IsWrapped is set to false on the MessageContractAttribute, these elements will
be direct children of the SOAP body element. If IsWrapped is set to true, they will be wrapped
within a child element, an element named using either the WrapperName property if it is set
explicitly or the Message contract name. This attribute, outlined in Table 1-7, contains several
properties to provide control over how it is used.
Reasons for Using Message Contracts
Now, why might you want to use a Message contract?
ProtectionLevel Enables the Service contract to specify constraints on how messages to
all operations in the contract are protected on the wire, that is, whether
they are signed and encrypted. See Chapter 8 for more about security.
Actor A URI value indicating which actor is the intended target of the header.
By default, the receiving service is assumed.
MustUnderstand Indicates whether the recipient of the header (designated through the
Actor property) is required to process this header. If this property is set
to true and the actor doesn’t understand the header, the actor should
issue a fault.
Relay Indicates whether this header should be forwarded to the next recipient
of the message in the event the message is not being processed by the
actor.
Table 1-7 Named Parameter Options for the MessageBodyMemberAttribute
Named Parameter Description
Name Controls the name of the serialized body element.
Namespace Supplies a namespace for the body element and its children unless otherwise
overridden at the type level.
ProtectionLevel Enables the Service contract to specify constraints on how messages to all
operations in the contract are protected on the wire, that is, whether they
are signed and encrypted. See Chapter 8 for more about security.
Order Controls the order of each element in the schema. By default, if this property
is not set explicitly, the data members appear alphabetically, followed
by elements for which this property is set explicitly. The same rules are
used to apply ordering as are used with Data contracts. (See the section
titled “The DataMemberAttribute.”)
Table 1-6 Named Parameter Options for the MessageHeaderAttribute
Named Parameter Description
Lesson 2: Defining Structural Contracts 43
Control over Message Body Wrapping If you don’t use any Message contracts in your service
operation signatures, the WCF default behavior is to serialize messages so that the SOAP
body element contains a child wrapper element that exactly matches the operation name and
wraps any parameters (or return values for a response message). If there aren’t any parameters,
this element will be empty in the inbound (or request) message; similarly, if the return type is
void, this wrapper element will be empty on the outbound (response) message.
NOTE Message contracts must be used all or none
There isn’t any partial usage of Message contracts. After you introduce a Message contract into an
operation’s signature, you must use a Message contract as the only parameter type and as the
return type of the operation. This is in contrast with the more typical scenario in which you have a
parameter list or return value composed of Data contracts or serializable types.
When you declare a MessageContractAttribute, the named parameter IsWrapped controls
whether this wrapping in an element (named the same as the operation name) should happen.
Thus, when you set IsWrapped to false, this wrapping does not occur, and the child of the
SOAP body would simply be the collection of MessageBodyMember elements within the Message
contract.
Controlling wrapping can be important when interoperating with other platforms because
they might serialize their SOAP messages differently from the default way WCF does, which is
to wrap them.
Supplying Custom Headers You might sometimes need to send along private elements in
your SOAP messages, and defining Message contracts supports this. Two common reasons for
doing this are that:
􀁑 You have your own security mechanism in place, so you need to pass along your own
authentication token in a private SOAP header.
􀁑 Consumers of your service might have to include some sort of license key (or developer’s
key) to access the service at run time. In such cases, a SOAP header is a reasonable place
for such a field.
Putting the Pieces Together
Taking what you have learned in the previous few sections, put it all together by examining
how Message contracts are used in some sample code. In the interest of keeping things simple,
suppose you have a service that has one operation that simply returns some contact info about
the service provider. As such, you might propose the following contract:
' VB
_
Public Class ContactInfo
_
44 Chapter 1 Contracts
Public PhoneNumber As String
_
Public EmailAddress As String
End Class
_
Public Interface ISomeService
_
Function GetProviderContactInfo() As ContactInfo
End Interface
// C#
[DataContract()]
public class ContactInfo
{
[DataMember()]
public string PhoneNumber;
[DataMember()]
public string EmailAddress;
}
[ServiceContract()]
public interface ISomeService
{
[OperationContract()]
ContactInfo GetProviderContactInfo();
}
However, then suppose that access to your service requires a license key. That is, every message
sent to the service must be checked for license key validity. Because a SOAP header is a
reasonable place to store a license key, you can rework this Service contract to use Message
contracts. The following code does just that by defining both a Request Message contract and
a Response Message contract. It even includes a simplistic implementation that validates the
license key.
' VB
_
Public Class ContactInfo
_
Public PhoneNumber As String
_
Public EmailAddress As String
End Class
_
Public Class ContactInfoRequestMessage
_
Public LicenseKey As String
Lesson 2: Defining Structural Contracts 45
End Class
_
Public Class ContactInfoResponseMessage
_
Public ProviderContactInfo As ContactInfo
End Class
_
Public Interface ISomeService
_
_
Function GetProviderContactInfo( _
ByVal reqMsg As ContactInfoRequestMessage) _
As ContactInfoResponseMessage
End Interface
Public Class SomeService
Implements ISomeService
Public Function GetProviderContactInfo( _
ByVal reqMsg As ContactInfoRequestMessage) _
As ContactInfoResponseMessage _
Implements ISomeService.GetProviderContactInfo
If reqMsg.LicenseKey <> ValidLicenseKey Then
Dim msg As String = "Invalid license key."
Throw New FaultException(Of String)(msg)
End If
Dim respMsg As ContactInfoResponseMessage
respMsg = New ContactInfoResponseMessage()
respMsg.ProviderContactInfo = New ContactInfo()
respMsg.ProviderContactInfo.EmailAddress = "sam@fabrikam.com"
respMsg.ProviderContactInfo.PhoneNumber = "123-456-7890"
Return respMsg
End Function
Private Const ValidLicenseKey As String = "abc-1234-alpha"
End Class
// C#
[DataContract()]
public class ContactInfo
{
[DataMember()]
public string PhoneNumber;
[DataMember()]
public string EmailAddress;
}
46 Chapter 1 Contracts
[MessageContract(IsWrapped = false)]
public class ContactInfoRequestMessage
{
[MessageHeader()]
public string LicenseKey;
}
[MessageContract(IsWrapped = false)]
public class ContactInfoResponseMessage
{
[MessageBodyMember()]
public ContactInfo ProviderContactInfo;
}
[ServiceContract()]
public interface ISomeService
{
[OperationContract()]
[FaultContract(typeof(string))]
ContactInfoResponseMessage GetProviderContactInfo(
ContactInfoRequestMessage reqMsg);
}
public class SomeService : ISomeService
{
public ContactInfoResponseMessage GetProviderContactInfo(
ContactInfoRequestMessage reqMsg)
{
if (reqMsg.LicenseKey != ValidLicenseKey)
{
const string msg = "Invalid license key.";
throw new FaultException(msg);
}
ContactInfoResponseMessage respMsg =
new ContactInfoResponseMessage();
respMsg.ProviderContactInfo = new ContactInfo();
respMsg.ProviderContactInfo.EmailAddress = "sam@fabrikam.com";
respMsg.ProviderContactInfo.PhoneNumber = "123-456-7890";
return respMsg;
}
private const string ValidLicenseKey = "abc-1234-alpha";
}
Note that, because you used IsWrapped = false, the request and response messages will not
be wrapped inside an element named ContactInfoRequestMessage in the request and
response SOAP bodies. Rather, the children of the body element will be the elements in the
ContactInfoRequestMessage that are annotated with the MessageBodyMemberAttribute for the
Lesson 2: Defining Structural Contracts 47
request message. Similarly, with the ContactInfoResponseMessage, its members marked with
the MessageBodyMemberAttribute will be direct children of the body in the response message.
Versioning of Data Contracts
One of the main advantages of service orientation is that it facilitates decoupling a service from
its consumers. The primary driver behind this decoupling is that consumers need only know
about the XML format of the messages they send to the service; they do not have a binary-level
code dependency on the service as there was with component-based middleware technologies
of the past, such as .NET Remoting, DCOM, CORBA, and so on. But is this enough? It is if the
service never changes, but how likely is that? To be truly decoupled, services should also be
version tolerant. Ideally, that means that any version of the client should be able to consume
any version of the service. When a service exposes a Data contract, the moment it has its first
consumer, the service and consumer share that Data contract thereafter to some extent. As
such, the true goal for version tolerance is to enable both the service and the client to evolve
their versions of the Data contract separately. To enable such version tolerance, WCF supports
what are generally referred to as backward and forward compatibility.
To explore this notion of version tolerance a little further, and WCF’s support for it, subsequent
sections look at the following three versioning scenarios:
􀁑 New members have been added to a Data contract.
􀁑 Members from a Data contract are missing.
􀁑 Roundtripping is supported, meaning that when a new version of a Data contract is
passed to and from an old version, the transmission requires both backward and forward
compatibility.
Adding New Members to a Data Contract
By far the most common version change that occurs with Data contracts is that a new member
is added. However, the DataContractSerializer will simply ignore any new members when deserializing
the type, so both the service and the client can accept data with new members that
were not part of the original contract.
Members Missing from a Data Contract
The WCF default policy is to try to allow the service to accept data with missing members or
to return data with missing members to the client. How does it do this? Suppose one entity is
trying to send data to a recipient (this could be either client to service or service to client), but
it is missing a member that the recipient is expecting to find there. It might have done so intentionally
(although hopefully not), but the more likely cause is that the sender knows only
about an older version of the Data contract while the recipient knows about a newer version,
one with new members. What happens in this scenario? For any members that are optional
48 Chapter 1 Contracts
(IsRequired is set to false, the default) but are nonetheless expected to be found but aren’t, the
DataContractSerializer will simply go ahead and deserialize them to their default value—that is,
null for reference types and zero values for value types. For members that are not optional
(IsRequired is set to true), an exception will be thrown.
Is this the desired behavior? Likely, if the element is not required (the IsRequired property of
the DataMember attribute is set to false, which is the default). But what if the element is
required? Then an exception is probably the best of all possible things to do because, presumably,
the element was required for a good reason. However, one should go to all lengths to
avoid this scenario; when adding a new field to a Data contract, you should do everything in
your power to make the field an optional element (that is, IsRequired is set to false).
Roundtripping
The situations discussed so far might be adequate in many scenarios, but what if you have a
v1.0 client conversing with a v2.0 service that has added new members to its Data contract
that the v1.0 client obviously knows nothing about; suppose further that the service returns
data (conforming to the new contract) to the client and is expecting the client to modify certain
data in the message and, ultimately, send it back to the service. Is there any way the client
will be able to successfully return the data it knows about without losing the unknown data it
was sent? This new-to-old-to-new interaction is called a versioning roundtrip, and WCF does
have some built-in support for it.
This support comes in the form of the IExtensibleDataObject interface and how you implement
it on your Data contract. Consider how the following Data contract uses this technique:
' VB
_
Public Class Task
Implements IExtensibleDataObject
_
Public Description As String
' Etc...
Public Property ExtensionData() _
As ExtensionDataObject _
Implements IExtensibleDataObject.ExtensionData
Get
Return _extensionData
End Get
Set(ByVal value As ExtensionDataObject)
_extensionData = value
Lesson 2: Defining Structural Contracts 49
End Set
End Property
Private _extensionData As ExtensionDataObject
End Class
// C#
[DataContract(Namespace =
"http://schemas.fabrikam.com/2008/04/tasks/")]
public class Task : IExtensibleDataObject
{
[DataMember(IsRequired = true, Order = 1)]
public string Description;
// Etc...
public ExtensionDataObject ExtensionData
{
get
{
return _extensionData;
}
set
{
_extensionData = value;
}
}
private ExtensionDataObject _extensionData;
}
In this code, the _extensionData object is simply a placeholder in which the DataContractSerializer
(because it sees that the contract implements the IExtensibleDataOject interface) can package
any unknown (or extra) data that it comes across and doesn’t know anything about. Thus in
a roundtrip scenario, the client could keep this data (unknowingly packaged along with an
extensible data object) and, when it sends its message back to the service, the DataContract-
Serializer will once again come to the rescue by serializing it as part of the message. Because
the service knows about this data, it can properly deserialize it and use it intelligently.
Controlling Serialization
This section covers the tools you need to gain control over serialization as is required in some
situations. It discusses those situations and explains how you can declare the right serializer
to use.
50 Chapter 1 Contracts
Real World
Peter Madziak
Frequently, you will be defining your services in a domain in which open standards initiatives
exist that have worked toward defining XSDs, WSDL, or both, to encourage
interoperability among the participants in the given domain. These standardization
efforts are aimed at ensuring that, typically within business to business (B2B) scenarios,
the providers can rely on the format of the messages being sent and the type of processing
that will occur within the service endpoints receiving the messages.
An example of this would be the Open Travel Alliance (OTA), a group consisting of a
wide variety of participants from within the travel industry, which has defined XSD
request and response schemas for a vast array of business transactions that could occur
within the context of B2B travel scenarios. In such cases, it is far better to adopt these
standard schema and WSDL definitions and, thereby, help the drive toward true standardization
instead of inventing your own standard.
MORE INFO Open Travel Alliance
For more information on the OTA, see http://www.opentravel.org/.
This section discusses how you can use WCF to ensure that your services send and receive
messages in the correct XML format when the starting point is a preexisting (hopefully standard)
XML schema as opposed to WCF Data contracts.
Serialization vs. Encoding
The terms serialization and encoding are used in so many different ways in the world of software
that it is worthwhile pausing here to clarify how these terms are used in the context of
WCF. This will help set the context around the topic of this lesson.
Suppose you have an object—perhaps a Data contract object or a serializable object—that you
are working with in the context of a WCF service-type implementation, and you return it from
one of your service operations. When this object is passed off to the WCF plumbing, it is serialized
to a Message object (whose class is defined in the WCF plumbing in the System.Service-
Model.Channels namespace). The resulting Message object is the WCF way of representing a
SOAP message but only in the sense of an abstract XML InfoSet representation of it. Don’t
think angle brackets because, as you’ll see in a moment, the Message object might never be represented
that way. WCF provides two serializers to do this job of rendering an object graph to
a WCF Message object:
Lesson 2: Defining Structural Contracts 51
􀁑 The DataContractSerializer, new with WCF
􀁑 The XmlSerializer that has been part of .NET from the outset
At a later stage in the chain of channels comprising the WCF plumbing, there will be an
encoder whose job is to encode the Message object (the abstract InfoSet representation of the
SOAP message) to a byte stream in a particular concrete syntax. The resulting message sent out
over the wire might well be the angle bracket–laden XML, but then again, it might not be. WCF
provides three encoders out of the box to handle this job of producing a Message object as a
byte stream to send over the wire: the text encoder to do standard XML text encoding and two
others to do MTOM encoding and WCF-to-WCF binary encoding, respectively. Chapter 2 discusses
these encoders.
The Format Attributes
WCF provides two attributes, namely XmlSerializerFormatAttribute and DataContractFormat-
Attribute, that you can use to declare that WCF uses a specific serializer, namely the Xml-
Serializer and the DataContractSerializer, respectively. Both of these attributes have a Style
property that enables you to control which style of SOAP is to be used, Rpc (remote procedure
call) or Document. The XmlSerializerFormatAttribute has another property, called Use,
that enables you to control whether the serializer uses the Literal or Encoded approach to
constructing SOAP messages. Although these attributes can be applied to your Data contracts,
the more typical scenario is to apply them at the service level because your Data contracts
could be used in more than one service. The following code sample shows in bold two
examples of their usage:
' VB
_
_
Interface ISomeLegacyService
_
Function SomeOp1( _
ByVal name As String) As String
End Interface
_
_
Interface ISomeRpcService2
_
Function SomeOp2( _
ByVal name As String) As String
End Interface
// C#
[ServiceContract()]
52 Chapter 1 Contracts
[XmlSerializerFormat(Style=OperationFormatStyle.Rpc,
Use=OperationFormatUse.Encoded)]
interface ISomeLegacyService
{
[OperationContract()]
string SomeOp1( string name);
}
[ServiceContract()]
[DataContractFormat(Style=OperationFormatStyle.Rpc)]
interface ISomeRpcService2
{
[OperationContract()]
string SomeOp2( string name);
}
Consider the following points in reference to using these attributes:
􀁑 For both the DataContractFormatAttribute and the XmlSerializerFormatAttribute, the
default style is Document. The Rpc style is outdated, so you’ll probably never encounter
it. However, if you do, WCF can support it.
􀁑 The DataContractSerializer is the default serializer WCF uses, so you need only use the
DataContractFormat attribute when you need to specify the Rpc style, which should
almost never happen.
􀁑 The primary usage of these format attributes is to declare explicitly that WCF should use
the XmlSerializer instead of the DataContractSerializer.
􀁑 The XmlSerializerFormat attribute enables you to specify the Use to be either Literal or
Encoded, but again, Literal is the default and Encoded is an outdated SOAP artifact that
you will likely never encounter.
The DataContractSerializer vs. the XmlSerializer
The DataContractSerializer has the following benefits:
􀁑 Its opt-in approach provides nice control over Data contracts for developers. Your Data
contract classes can be equipped with other elements and validation logic that need not
be opted in.
􀁑 It is very fast. It is targeted at a very small, simple subset of the XML InfoSet and is
focused on speed instead of on being comprehensive.
However, the fact that it targets a small subset of XML also means that there are many complex
XSDs for which the DataContractSerializer is not well equipped to handle. The Data-
ContractSerializer will always be able to serialize to XML; it’s just that, in many cases, the
structure of the resulting XML might not be acceptable for your needs. However, that is
where the XmlSerializer comes in. It can be used to work with complex XML schemas, as
you’ll see in the next section.
Lesson 2: Defining Structural Contracts 53
MORE INFO The DataContractSerializer Support for XSD
Visit http://msdn2.microsoft.com/en-us/library/ms733112.aspx for details about the DataContract-
Serializer support for XSD.
Building XML Schema–Driven Services
Sometimes you might need to start from an existing XML schema. As mentioned in the
“Real World” sidebar at the start of the “Controlling Serialization” section, this is often the
case when you are working in an industry in which there exist well-defined, open-standard
schemas. You can build WCF services in a schema-driven approach if you follow these
steps:
􀁑 You design your XML schemas or work with existing standard schemas.
􀁑 You generate code from the schemas. To generate classes from a schema, you can use the
XSD command-line tool, as you’ll do in the lab for this lesson.
􀁑 You mark your Service contract to use the XmlSerializer.
􀁑 You declare service operations to:
􀁔 Receive a single parameter based on the generated type from one of your schema
types.
􀁔 If not one-way, similarly return an object of a class generated from one of your
schema types.
􀁑 From a client proxy perspective, you will need to use the /serializer:XmlSerializer option.
Chapter 4 returns to this point.
The lab you start next takes you through these steps, working with two schemas from the
travel industry.
Quick Check
1. You have a Data contract specifying a Person class from which you derive a Customer
class. Does a Customer object automatically have a Data contract as well?
2. Your company has its own proprietary authentication mechanism, and you are
required to authenticate every message coming into the service. What is the best
way to handle using this mechanism with WCF?
3. Can you support the Rpc SOAP style by using the DataContractSerializer?
54 Chapter 1 Contracts
Quick Check Answers
1. No. The Data contract is not inherited, so any derived class, such as the Customer
class, would have to be explicitly declared as having a Data contract as well.
2. Likely the best way to handle this would be to design a Message contract that
accepts these proprietary authentication tokens in the header.
3. Yes. You need only adorn your service with the DataContractFormatAttribute and
explicitly set the attribute’s Style property to OperationFormatStyle.Rpc.

Friday, April 29, 2011

Using PictureBox on windows form to render whatever image you want at runtime !

My scenario here is to display a critical error icon on my custom dialogue box form. In case if we are showing a System.Windows.Forms.MessageBox, we can pass the parameter as ' MessageboxIcon.Error '  and it will show the error icon on the messagebox.

 But my requirement here is different.

So, I placed a PictureBox control on the form, named 'pcIcon',  and painted it with SystemIcons.Error.


Design:


PictureBox has an event called Paint. We can handle that and it is there we have to paint it with our desired image.

Code:


Finally the displayed Custom Dialogue Box with Error Icon :

Call  ShowDialog() method of the designed form, optionally passing the 'owner' parameter as 'Me' (in vb) / 'This' (in c#).



Tuesday, December 7, 2010

Choosing between Abstract class and Interface

The choice of whether to design your functionality as an interface or an abstract class (a MustInherit class in Visual Basic) can sometimes be a difficult one. An abstract class is a class that cannot be instantiated, but must be inherited from. An abstract class may be fully implemented, but is more usually partially implemented or not implemented at all, thereby encapsulating common functionality for inherited classes. For details, see Abstract Classes.

An interface, by contrast, is a totally abstract set of members that can be thought of as defining a contract for conduct. The implementation of an interface is left completely to the developer.

An advantage of Abstract class over Interface
If you want to have additional functionalities for the interface, you must implement the new ones in all of the classes that implement the changed interface. The code will not work until you make the change. But if you want to have additional functions to the Abstract class, you can have default implementation. Your code still might work without many changes.

An advantage of Interface over Abstract class
A class can inherit multiple interfaces but can inherit only one class.

When to Use Abstract and When to Use Interface:

Let me explain it with reference to the scenario.
Let us take a classification called Human. As it is a very general classification, I can put all the Human related common data in Abstract class.These common data could be First Name, Last Name, Gender, Education, Occupation, Residence, etc. with some functions as virtual (or overridable), e.g., an occupation which differs from human to human.

Aim of Interface: We want the implementing object to acquire this ability.
Aim of Abstraction: We want the derived object to belong to some group. Abstraction gives the Identity to the derived object.

The sentence "Object A is a Human" is more meaningful than the sentence "Object A is an object which has the ability to walk." (Human can walk, an animal, a bird, a machine - consider it is a robot ... that can also walk.)

Why I chose interfaces IEat, IWalk, IDance and ISing

I may want Object A to walk in the morning, to eat in the afternoon or to dance in the evening, or I may not be aware at a particular time what these objects should be doing. The capability of Object A at a particular time is unknown to me. Also every derived object may need not posses the quality of walking, or dancing, or singing. An infant cannot walk, as you know everybody cannot dance and sing. So I created these interfaces so that I can define the combination of these capabilities for different objects explicitly.


Refer to the image below for a more clearer view.



Take an example of .NET interfaces IDisposable or IComparable. We implement these interfaces only if necessary. We implement IDisposable mostly when we want to handle COM components and IComparable to compare and sort the objects in an Array.

If you want your class to have an Identity of Form, you must inherit Form class and you can add the ability to dispose, by implementing IDisposable, only if you want to dispose it manually.

Reusability
Let us consider the same abstract Human class which has the virtual function Eat instead of an Interface IEat.
Now I want to create a class called Bird. As a Bird can also eat, I want to reuse the function which is already there in Human class. Suppose, just because abstract Human class has the function to eat, I cannot derive a Bird class from that. I will tend to change the Bird's identity by doing so, or I may load unnecessary properties to the Bird that could be an education, or employment, or may be the last name. Even worse I may need to change the abstract Human class so as to include the common behaviors of Bird category. This is totally senseless and messes up the class and objects. Instead, I can have another Abstract class for Birds and choose to have an interface called IEat, which could be implemented by an object of Human and also an object of Bird.







Polymorphic Behavior:
Both interfaces and abstract classes are useful for component interaction. If a method requires an interface as an argument, then any object that implements that interface can be used in the argument. For example:
 
' Visual Basic
Public Sub Spin (ByVal widget As IWidget)
End Sub
// C#
public void Spin (IWidget widget)
{}
This method could accept any object that implemented IWidget as the widget argument, even though the implementations of IWidget might be quite different. Abstract classes also allow for this kind of polymorphism, but with a few caveats:
  • Classes may inherit from only one base class, so if you want to use abstract classes to provide polymorphism to a group of classes, they must all inherit from that class.
  • Abstract classes may also provide members that have already been implemented. Therefore, you can ensure a certain amount of identical functionality with an abstract class, but cannot with an interface.

Conclusion :

  • Abstract class gives an Identity to the derived object.
  • Interface extends the ability of an object.
  • Interfaces give polymorphic behavior.
  • Abstract class also gives polymorphic behavior. But it is more meaningful to say that Abstract class simplifies versioning, as the base class is flexible and inheriting class can create many versions of it by additional functions and also by implementing Interfaces.
  • Interfaces and Abstract classes both promote reusability.

Here are some recommendations to help you to decide whether to use an interface or an abstract class to provide polymorphism for your components.
  • If you anticipate creating multiple versions of your component, create an abstract class. Abstract classes provide a simple and easy way to version your components. By updating the base class, all inheriting classes are automatically updated with the change. Interfaces, on the other hand, cannot be changed once created. If a new version of an interface is required, you must create a whole new interface.
  • If the functionality you are creating will be useful across a wide range of disparate objects, use an interface. Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing common functionality to unrelated classes.
  • If you are designing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract class.
  • If you want to provide common, implemented functionality among all implementations of your component, use an abstract class. Abstract classes allow you to partially implement your class, whereas interfaces contain no implementation for any members.

References :
CodeProject
MSDN

Monday, August 23, 2010

URL Routing on IIS7 and ASP.NET 3.5 with SP1

Purpose : To allow users browse your site using extensionless and user-friendly urls.
Step1: Add a Reference to System.Web.Routing to Your Project
Step2: 
Add UrlRoutingModule to 'httpModules' under <system.web> and to 'modules' under  <system.webServer>;
Add UrlRoutingHandler to 'handlers' section under <system.webServer>

<configuration>
   ...

   <system.web>
      ...
      <httpModules>
         ...
         <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </httpModules>

   </system.web>

   <system.webServer>
      <validation validateIntegratedModeConfiguration="false"/>
      <modules>
         ...
         <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </modules>


      <handlers>
         ...
         <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      </handlers>
      ...
   </system.webServer>

</configuration>

Step 3: Define the Routes in Global.asax

Define one to many routes in Application_Start event of global.asax.

Here in this example defined a route to 
SchoolType/SchoolName - used to view school detail page. (where actually you have to go to this page by virtual path 'ViewSchool.aspx?schoolid = 14')


<%@ Import Namespace="System.Web.Routing" %>
<script runat="server">
void Application_Start(object sender, EventArgs e) 
{
     RegisterRoutes(RouteTable.Routes);
}

void RegisterRoutes(RouteCollection routes)
{
    routes.Add("ViewSchool", new Route("{SchoolType}/{*SchoolName}", new   SchoolRouteHandler()));
}
</script>

Step 4: Create the Route Handler Classes
 A route handler class is a class that is passed information about the incoming request and must return an HTTP Handler to process the request. It must implement the IRouteHandler  interface and, as a consequence, must provide at least one method - GetHttpHandler - which is responsible for returning the HTTP Handler (or ASP.NET page) that will process the request.
Typically, a route handler performs the following steps:
  1. Parse the URL as needed
  2. Load any information from the URL that needs to be passed to the ASP.NET page or HTTP Handler that will handle this request. One way to convey such information is to place it in the HttpContext.Items collection, which serves as a repository for storing data that persists the length of the request.
  3. Return an instance of the ASP.NET page or HTTP Handler that does the processing

public class SchoolRouteHandler : IRouteHandler
{
     public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string schoolType = requestContext.RouteData.Values["SchoolType"] as string;
        string schoolName = requestContext.RouteData.Values["SchoolName"] as string;
      
        if (string.IsNullOrEmpty(schoolName) || string.IsNullOrEmpty(schoolType))
            return BuildManager.CreateInstanceFromVirtualPath("~/schoolnotfound.aspx", typeof(Page)) as   
            Page;
        else
        {
            //Code here to get school id from database 
           //store values, whichever you want to pass them to .aspx page

            HttpContext.Current.Items["SchoolType"] = schoolType;
            HttpContext.Current.Items["SchoolID"] = schoolid;

            return BuildManager.CreateInstanceFromVirtualPath("~/viewschool.aspx", typeof(Page)) as Page;
        }
            return BuildManager.CreateInstanceFromVirtualPath("~/schoolnotfound.aspx", typeof(Page)) as         Page;
    }
}

Step 5: Create the ASP.NET Pages That Process the Requests

protected void Page_Load(object sender, EventArgs e)
   //Retrieve values back from httpcontext
   Int64 schoolid = Convert.ToInt64(
HttpContext.Current.Items["schoolid"]);

If you do till here it will work fine on your local system using development server.  But, when you host the website on a shared server you get HTTP 404 page. This means IIS receives the request and it serves the page configured for HTTP 404. Generally this is a 404.html file that resides in IIS directory. IIS does not send the request to ASP.NET handler and thus you cannot intercept 404 requests. So, if you can forward all HTTP 404 to ASP.NET, you can serve such extensionless URL. In order to forward HTTP 404 to ASP.NET ISAPI, all you need to do is configure IIS to redirect to some .aspx extension when a missing extensionless url is hit.

Step6:
Add below section to your web.config , under <system.webserver>
<httpErrors errorMode="Custom">
     <remove statusCode="404" subStatusCode="-1" />
     <error statusCode="404" prefixLanguageFilePath="" path="/404.aspx" responseMode="ExecuteURL" />
</httpErrors>

When you will request an URL like "www.findaschool.in/preschools/drskids" it will redirect to "www.findaschool.in/404.aspx?404;http://www.findaschool.in/preschools/drskids". From Global.asax BeginRequest event, capture this URL and see whether it's an extensionless URL request. If it is, do your URL rewriting stuff for such extensionless URL.


protected void Application_BeginRequest(object sender, EventArgs e)
{
      string url = HttpContext.Current.Request.Url.AbsolutePath;
   
      // HTTP 404 redirection for extensionless URL or some missing file
      if (url.Contains("404.aspx"))
      {
          // On 404 redirection, query string contains the original URL in this format:
          // 404;http://www.findaschool.in/preschools/drskids    
          string[] urlInfo404 = Request.Url.Query.ToString().Split(';');
          if (urlInfo404.Length > 1)
          {
              string originalUrl = urlInfo404[1];
System.Uri rwUri = new Uri(originalUrl);
              HttpContext.Current.RewritePath(rwUri.PathAndQuery); 
}
}
}

More detailed information at below links:
  •  http://www.4guysfromrolla.com/articles/051309-1.aspx
  •  http://www.codeproject.com/KB/aspnet/extensionless.aspx
  •  http://blogs.msdn.com/b/tmarq/archive/2010/04/01/asp-net-4-0-enables-routing-of-extensionless-urls-without-impacting-static-requests.aspx

Friday, August 20, 2010

Uploading a large file using FileUpload Control in ASP.NET

By default FileUpload control in asp.net uploads upto 4MB size of files and it doesn't allow 'exe' files.

To increase the file size limit that a fileupload control can upload, just add the following line to web.config

< system.web >
< httpruntime executiontimeout="500" maxrequestlength="4096" >
< /system.web >

Here 'executionTimeout' in milliseconds and 'maxRequestLength' in kb. So, increase the maxRequestLength to upload large files.