Fix to Generate Contract Code for Dates


Here's a bonus entry left from last week. Last week I ran a series covering fixes for WCF that may be hard to find and explaining the details behind each problem.

Contract code generation takes a system-independent description of the types used for a messaging operation and generates source code instructions for working with those types. XML schema is an example of a definition language for describing a set of type constraints. Some of the constraints in an XML schema may map very easily to source code in the target language that you're using while other constraints may only map with considerable difficulty. An imperfect map generally results in a source code type that is a broader substitute for the intended type.

The reference importer in svcutil uses type equivalence to recognize types in assemblies that represent the metadata being imported. When there is an imperfect map, the contract type may differ from the mapped type even though it is the closest equivalent to the mapped type. For example, there is an imperfect map for the XML schema date data type because in C# there is no way to express dates independently of times.

In the original code this means that a date in a schema is mapped to the broader string type, which is not equal if compared again to the original date data type. This causes source code generation to fail when referencing an existing contract that has one of these broadening conversions. The fix changes the notion of equivalence when comparing types to identify the output of a broadening operation as still being equal when comparing type references.

This fix is available for download from KB article 960415.

Comments (4)

  1. Talking about Contract Generation fixes in svcutil, I just stumbled across another issue.

    What I want do is the following:

    * visually model my data in XSD

    * generate data contract from XSD to send my object forth and back using WCF

    * load/persist this very exact object from NHibernate

    The reason this doesn’t work out of the box is that svcutil generates List<T> for my collections whereas NHibernate needs IList<T>.

    Looking at svcutil you see it uses XsdDataContractImporter that creates a CodeDom from my XSD. Lovely. So what I did, was basically using XsdDataContractImporter to get a standard CodeDom representation and then changing all List<T> to IList<T>.

    This works like charm, except for on little detail.

    To serialize the items of a collection different from the typename the datacontractserializer uses the following construct:

    [System.Runtime.Serialization.CollectionDataContractAttribute(Name="MySecurity.IdentifiersType", ItemName="Identifier")]

    public class IdentifiersType : System.Collections.Generic.List<IdentifierType> { }

    This is the only way to name the items in a collection (and imho a bad one)

    What we need is somehing like an extension of the DataMemberAttribute so that I can do the following:

    [DataMemberAttribute(ItemName="Identifier")]

    public IList<myIdentifierType> Identifiers { get;set }

    This has no effect on WCF-Serialization in general, only the serialized object is not valid against our XSD.

  2. Hi Tobias,

    Couldn’t you use the /collectionType:<type> option on svcutil to do that mapping if you don’t like the type it’s using?  That is a global flag though so if you only want to change a portion of the type references, then you would have to do that with another approach as you’ve outlined.

  3. You tell me now ;-).

    /ct:System.Collections.Generic.IList`1

    works to the point where it creates the new collection type "derived" from the interface. It does not build because the class does not implement the interface members.

    [CollectionDataContractAttribute(…..,ItemName="MyItemName")]

    public class MyListType : IList<myType>

    {

    }

    and as [CollectionDataContractAttribute] only works on classes, when using collection interfaces in data contracts, there is no way to serialize the items of the collections according to the xsd specification.

  4. Hi Tobias,

    If you need specific control over the settings on the type then something like the workaround may be the best option.

Skip to main content