Welcome to Windows Communication Foundation (WCF)
Top Tasks :

WCF Team Bloggers

Browse by Tags

All Tags » Proxies » Serialization   (RSS)

  • Getting Better Time Formats

    Orcas introduced a new DateTimeOffset class that is easier to use for representing absolute times than the original DateTime class. However, if you run svcutil on a contract that contains a DateTimeOffset, you'll get an ugly generated structure because DateTimeOffset isn’t recognized as a natively supported type by the system. A new class is generated by svcutil to match the schema for DateTimeOffset in the metadata. namespace System { using System.Runtime.Serialization; [DebuggerStepThroughAttribute()] [GeneratedCodeAttribute( "System.Runtime.Serialization" , "3.0.0.0" )] [DataContractAttribute(Name= "DateTimeOffset" , Namespace= "http://schemas.datacontract.org/2004/07/System" )] public partial struct DateTimeOffset : IExtensibleDataObject { private ExtensionDataObject extensionDataField; private DateTime DateTimeField; private short OffsetMinutesField; public ExtensionDataObject ExtensionData { get { return this .extensionDataField; } set { this .extensionDataField = value ; } } [DataMemberAttribute(IsRequired= true )] public DateTime DateTime { get { return this .DateTimeField; } set { this .DateTimeField = value ; } } [DataMemberAttribute(IsRequired= true )] public short OffsetMinutes { get { return this .OffsetMinutesField; } set { this .OffsetMinutesField = value ; } } } } There's a new option on svcutil, /targetClientVersion:Version35, that can be used to indicate that code generation should use new features in Orcas. As far as I know, there are three places where this option makes a difference. DateTimeOffset is automatically added as a known type when referenced Asynchronous methods are generated using the Orcas event-based asynchronous model Additional LINQ types are supported during schema import for XmlSerializer Next time: Read Only Data Members Read More...
  • Avoiding Infinite Schema Chains

    I was working on some services with recursive data structures when I noticed that there were a few cases where I would get crashes while trying to generate proxy classes. The problems seemed to be around types that were a sequence of instances of themselves. That looks like this: < xs:schema xmlns:tns ="http://test" targetNamespace ="http://test" xmlns:xs ="http://www.w3.org/2001/XMLSchema" > < xs:complexType name ="CircularList" > < xs:sequence > < xs:element minOccurs ="0" maxOccurs ="unbounded" name ="CircularList" nillable ="true" type ="tns:CircularList" /> </ xs:sequence > </ xs:complexType > < xs:element name ="CircularList" nillable ="true" type ="tns:CircularList" /> </ xs:schema > When using message contracts I was able to fix the problem by moving the minOccurs and maxOccurs from the element to the containing sequence. This didn't change the meaning of the type when I examined the proxy. With data contracts, trying the same fix caused proxy generation to go into an infinite loop rather than crash, but that's not much of an improvement. The data contract serializer worked best when I defined an intermediate type to represent the sequence rather than directly including the list type in itself. These all look like bugs with schema analysis. Next time: Waiting for Ready Channels Read More...
  • Generating Types with Lists

    I have a data contract that contains a collection type but the generated proxy appears as an array. How can I make the proxy use a collection type as well? I've talked in the past about how the representation of a type in metadata is decoupled from the CLR representation of a type in the service. For example, if I have a data contract that uses a List: [DataContract] class Data { [DataMember] public List< string > data; } Then, the metadata representation of this data contract is actually described as an array because arrays are the only primitive type for collections in schema. < xs:schema xmlns:tns ="http://schemas.datacontract.org/2004/07/" elementformdefault ="qualified" targetnamespace ="http://schemas.datacontract.org/2004/07/" xmlns:xs ="http://www.w3.org/2001/XMLSchema" > < xs:import namespace ="http://schemas.microsoft.com/2003/10/Serialization/Arrays" > < xs:complexType name ="Data" > < xs:sequence > < xs:element xmlns:q1 ="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minoccurs ="0" name ="data" nillable ="true" type ="q1:ArrayOfstring" > </ xs:element > </ xs:sequence > < xs:element name ="Data" nillable ="true" type ="tns:Data" > </ xs:element > </ xs:complexType ></ xs:import ></ xs:schema > However, just as the metadata representation isn't coupled to the service, the metadata representation also isn't coupled to the client. You can on the client generate proxies with any type for this collection that similarly can be serialized or deserialized to an array. The mechanism for doing this with svcutil.exe is the /ct switch. The /ct switch, which stands for collectionType, allows you to give a qualified type name that is used for collection data types when generating a proxy. As an example, to get back to the original collection class used by the server, the proxy would need to be constructed using /ct:System.Collections.Generic.List`1 as the option passed to svcutil.exe. However, you could leave the proxy using arrays or provide a different collection class such as /ct:System.Collections.ObjectModel.Collection`1 and with any of these configurations the proxy would be able to exchange messages with the server. Next time: Setting the Configuration Name Read More...
  • Differences in Guid Serialization

    Why do the guids in my contract turn into strings when generating a client? You're probably mixing different types of serializers between the client and service. There's nothing wrong with this and the generated client will work correctly but you don't get the user-friendly types. To see why, let's look at the metadata. A guid in a contract with the DataContractSerializer generates a type in the http://schemas.microsoft.com/2003/10/Serialization/ namespace that looks like this: < xs:element name ="guid" nillable ="true" type ="tns:guid" /> < xs:simpleType name ="guid" > < xs:restriction base ="xs:string" > < xs:pattern value ="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" /> </ xs:restriction > </ xs:simpleType > On the other hand, a guid in a contract with the XmlSerializer generates a type in the http://microsoft.com/wsdl/types/ namespace that looks like this: < xs:simpleType name ="guid" > < xs:restriction base ="xs:string" > < xs:pattern value ="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" /> </ xs:restriction > </ xs:simpleType > These generated types are needed because a guid is not a primitive type. DataContractSerializer came after XmlSerializer so it recognizes both definitions but XmlSerializer has to rely on the schema when it sees a DataContractSerializer guid. Since the schema is based on a string type, the generated client field is a string. The same thing happens with other serializers that don't know how to map a particular schema pattern to a user-friendly type. Next time: TCP Throttling Read More...

Copyright © 2006 Microsoft Corporation. All Rights Reserved. | Terms of Use | Privacy Statement | Contact Us