Back to more _WCF_, or previously known as Indigo, postings...
I dont think a lot of people know about one of the aspects of WCF, which pertains
to how WCF serializes incoming messages before it sends it to the dispatcher and onto
your .NET typed code.
In .NET 1.*, ASMX disregards the ordering of the data elements in the received messages.
This means that for a XML Schema such as this:
[s:complexType name="CreditCard"]
[s:sequence]
[s:element name="AccountName" type="s:string" /]
[s:element name="CreditCardType" type="s:string" /]
[s:element name="CreditCardNo" type="s:string" /]
[s:element name="CreditCardExpiryDate" type="s:string" /]
[/s:sequence]
[/s:complexType]
If you send a _SOAP_ Message such as this (Take note that the ordering of [AccountName]
is not in-line with the above schema):
[soap:Envelope]
[soap:Header /]
[soap:Body]
[SubmitCreditCard]
[crdcard]
[CreditCardType]AMEX[/CreditCardType]
[CreditCardNo]1234567890[/CreditCardNo]
[CreditCardExpiryDate]08082088[/CreditCardExpiryDate]
[AccountName]William Tay[/AccountName]
[/crdcard]
[/SubmitCreditCard]
[/soap:Body]
[/soap:Envelope]
ASMX will allow the message to go through.
In WCF, there is strict enforcing of the ordering of the data elements. Lets take
a quick look:
WCF Code:
[DataContract()] _
Public Class CreditCard
[DataMember(Name:="CreditCardExpiryDate")] Private _CreditCardExpiryDate As
String
[DataMember(Name:="CreditCardType")] Private _CreditCardType As String
[DataMember(Name:="CreditCardNo")] Private _CreditCardNo As String
[DataMember(Name:="AccountName")] Private _AccountName As String
Public Property CreditCardType() As String
Get
Return _CreditCardType
End Get
Set(ByVal value As String)
_CreditCardType = value
End Set
End Property
Public Property CreditCardNo() As String
Get
Return _CreditCardNo
End Get
Set(ByVal value As String)
_CreditCardNo = value
End Set
End Property
Public Property CreditCardExpiryDate() As String
Get
Return _CreditCardExpiryDate
End Get
Set(ByVal value As String)
_CreditCardExpiryDate = value
End Set
End Property
Public Property AccountName() As String
Get
Return _AccountName
End Get
Set(ByVal value As String)
_AccountName = value
End Set
End Property
End Class
This will generate the schema:
[xs:complexType name="CreditCard"]
[xs:sequence]
[xs:element name="AccountName" nillable="true" type="ser:string" /]
[xs:element name="CreditCardExpiryDate" nillable="true" type="ser:string" /]
[xs:element name="CreditCardNo" nillable="true" type="ser:string" /]
[xs:element name="CreditCardType" nillable="true" type="ser:string" /]
[!-- I omitted some WCF-specific elements here for simplicity.--]
[!--I will blog more about this on a later date. See Below **--]
[/xs:complexType]
There is a reason I put the Public Property AccountName last
in my .NET 2.0/Indigo code above. I wanted to show that how you place the
property/field in code has no effect on the schema. If you keep a strong observant
eye on the resultant schema, you will notice that it is Alphabetical-Ordering dependent
and if I send the below message to it:
[s:Envelope]
[s:Header /]
[s:Body]
[SubmitCreditCard xmlns="http://demos.softwaremaker.net/SchemaDataOrdering"]
[crdcard]
[CreditCardExpiryDate]08082088[/CreditCardExpiryDate]
[CreditCardNo]1234567890[/CreditCardNo]
[CreditCardType]AMEX[/CreditCardType]
[AccountName]William Tay[/AccountName]
[/crdcard]
[/SubmitCreditCard]
[/s:Body]
[/s:Envelope]
It will result in a HTTP
Error Code: 500 (Internal Server Error). What this means is that you have
to keep the ordering of the dispatched message to the published schema or else
WCF will reject it.
The consensus from the field (I felt) is that while most of the projects doesnt
even feel the lack of schema-ordering enforcements in .NET 1.*, there may be certain
advanced validation scenarios that may need order checking at the schema level.
While I welcomed this extra checking, I hope it doesnt come with a performance
penalty.
The good news is that the Service.Runtime.Serialization.XMLFormatter,
which is used in WCF, is a lot better performer than its predecessor: the XMLSerializer. It does,
however, give the developer less control of the XML
Schema though. **WCF will add in its own special elements into the schema**. This will
aid in better message versioning and control that comes with the evolutionary
nature of distributed loosely-coupled messaging systems such as WCF. I will explain
more in a later blog post.
From what I understand, the WCF team is considering of adding an Order property
to the DataMemberAttribute to allow for added customization of this order.
Again, I feel that this is a good move as Alphabetical-Ordering dependency
will mean that developers may have to consider their naming
conventions in code should they require a validation check at the schema level.
What I would like is an attribute for me to turn-off schema data elements
ordering validation and checking should I choose to. In this case, the developers
on the field will be comfortable of the options they have at hand if validation
/ performance tradeoffs becomes an issue.
P/S: I used my own Manual
SOAP Post tool to create some of the scenarios here. You may want to download
it here.