Contents tagged with WCF

  • My All Time Favorite Posts

    Since this blog started, back in 2008, I wrote a lot of posts. I’d say some are still up to date. I picked a few of them, those I’m more proud of, in no particular order.

    ASP.NET Web Forms:




    Let me know what you think of them! Are there others you particularly enjoyed?


  • Exposing a Class as a COM+ WCF Service

    Remember COM+? Well, it is still around, and, in the days of WCF, it still usefull in certain scenarios, mostly because of the services COM+ offers OOTB (transactions, synchronization, object pooling, etc). For those of you that don't know how, I'm gonna demonstrate how you can expose an ordinary .NET class into both a COM+ component and a regular WCF service. Make sure you have Windows SDK 6.x or greater installed.


  • .NET Serializers


    As of version 3.5 SP1, .NET comes along with the following serializers:

    • System.Runtime.Serialization.Formatters.Binary.BinaryFormatter: binary serializer used in .NET Remoting, type information is included, understands System.Runtime.Serialization.ISerializable;
    • System.Runtime.Serialization.Formatters.Soap.SoapFormatter: SOAP (XML) serializer used in .NET Remoting, includes type information, understands System.Runtime.Serialization.ISerializable;
    • System.Runtime.Serialization.DataContractSerializer: XML serializer used in WCF, does not include type information;
    • System.Runtime.Serialization.Json.DataContractJsonSerializer: JSON serializer used in WCF, does not include type information;
    • System.Web.Script.Serialization.JavaScriptSerializer: JSON serializer;
    • System.Runtime.Serialization.NetDataContractSerializer: binary serializer used in WCF, includes type information;
    • System.Xml.Serialization.XmlSerializer: XML serializer used in ASP.NET Web Services (ASMX), type information is not included, understands System.Xml.Serialization.IXmlSerializable; 
    • System.Web.UI.LosFormatter: uses ObjectStateFormatter internally, does not account by itself;
    • System.Web.UI.ObjectStateFormatter: binary or text (base 64 encoded) serializer used in ASP.NET for storing items in view state, control state and session, type information is included, understands System.Runtime.Serialization.ISerializable.

    There isn't, however, a common interface for all of these serializers, and, in fact, they have quite different requirements.

    The base interfaces are:

    • System.Runtime.Serialization.IFormatter: for BinaryFormatter, SoapFormatter, NetDataContractSerializer and ObjectStateFormatter;
    • System.Runtime.Serialization.XmlObjectSerializer: for DataContractSerializer, DataContractJsonSerializer and NetDataContractSerializer;
    • XmlSerializer doesn't have any interface that specifies its behavior.

    The interfaces that can be used to control the serialization process are:

    • System.Runtime.Serialization.ISerializable: for all the IFormatter serializers;
    • System.Xml.Serialization.IXmlSerializable: for XmlSerializer.

    Also, there are a couple of attribute classes that can be used to control the serialization process:

    • System.Runtime.Serialization.OptionalFieldAttribute (IFormatter): field may be missing from the serialized content
    • System.Runtime.Serialization.NonSerializedAttribute (IFormatter): field is not serialized
    • System.Xml.Serialization.SoapAttributeAttribute (XmlSerializer)
    • System.Xml.Serialization.SoapElementAttribute (XmlSerializer)
    • System.Xml.Serialization.SoapEnumAttribute (XmlSerializer)
    • System.Xml.Serialization.SoapIgnoreAttribute (XmlSerializer)
    • System.Xml.Serialization.SoapIncludeAttribute (XmlSerializer)
    • System.Xml.Serialization.SoapTypeAttribute (XmlSerializer)
    • System.Xml.Serialization.SoapDocumentServiceAttribute (XmlSerializer): default format is Document
    • System.Xml.Serialization.SoapRpcServiceAttribute (XmlSerializer): default format is RPC
    • System.Xml.Serialization.SoapRpcMethodAttribute (XmlSerializer): method uses SOAP RPC format
    • System.Xml.Serialization.SoapDocumentMethodAttribute (XmlSerializer): method uses SOAP Document format
    • System.Xml.Serialization.XmlAnyAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlAnyElementAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlArrayAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlArrayItemAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlAttributeAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlChoiceIdentifierAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlElementAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlEnumAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlIgnoreAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlIncludeAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlRootAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlTextAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlTypeAttribute (XmlSerializer)
    • System.Xml.Serialization.XmlSchemaProviderAttribute (XmlSerializer): applied on a method that returns the XML schema
    • System.Runtime.Serialization.CollectionDataContractAttribute (XmlObjectSerializer)
    • System.Runtime.Serialization.DataContractAttribute (XmlObjectSerializer)
    • System.Runtime.Serialization.DataMemberAttribute (XmlObjectSerializer)
    • System.Runtime.Serialization.EnumMemberAttribute (XmlObjectSerializer)
    • System.Runtime.Serialization.IgnoreDataMemberAttribute (XmlObjectSerializer)
    • System.Runtime.Serialization.XmlSerializerFormatAttribute (XmlObjectSerializer): choose XmlSerializer instead of DataContractSerializer

    Note that the Soap* attributes are only considered if the SoapBindingUse.Encoded is set for the Use property of the binding, in ASP.NET Web Services, otherwise, its the Xml* attributes.

    It would be good to see a common interface (perhaps IFormatter, since it's the most common) for all of these serializers.

    Bookmark and Share


  • Circular References in WCF

    Updated: thanks to Nobody for the remark! 

    Suppose you want to transmit a list of items where possibly some of them refer to other items on the list. For example:


    public class MenuItem



        public String Text { get; set; }


        public String NavigationUrl { get; set; }


        public MenuItem Parent { get; set; }


    If you want to preserve bandwidth, and avoid circular references - for example, one menu item having itself as its parent - you should use the IsReference property on the [DataContract] attribute:

    [DataContract(IsReference = true)]

    This property exists since .NET 3.5 SP1 (and .NET 3.0 SP1, for that matter), and it makes it unnecessary to write a specific behavior to set the preserveObjectReferences on the DataContractSerializer class (see Sowmy's post: A welcome addition!


  • Using MTOM with WCF

    Suppose you want to transmit large binary contents (a file, for example) through WCF. In the usual way, you would use a classe decorated with a [DataContract] attribute, and you would have inside of it a property of type Byte[], marked with a [DataMember], where the actual contents would be placed. There is a problem with this solution, however: being SOAP based exclusively in text (it is just XML), if you want to send special characters inside of it, you must convert them into text, using common encoding techniques such as Basw 64. Now, WCF does this for you, you just have to supply the byte array, and it does all the work, the problem is that Base 64 typically increases the total size by 33%.

    The good news is that the good guys at W3C have developed a standard, named MTOM - Message Transmission Optimization Mechanism - that allows you to send binary content over the wire as is, that is, without translation to text. You can read about it here. I will not go into details, in order to use MTOM, you must do the folowing:

    1. The method that is sending MTOM content can only receive or return classes that have the [MessageContract] attribute, not [DataContract], or "primitive" types;
    2. All the byte array properties must have a [MessageBodyMember] attribute, not [DataMember] nor [MessageHeader], and all the other properties must have a [MessageHeader] attribute;
    3. Instead of Byte[] you can also pass a Stream object, the results are the same;
    4. All eventual classes that the parameter or return classes derive from must also have the [MessageContract] attribute;
    5. In the <binding> elements for you service (both client and server), you must set the messageEncoding attribute to Mtom.

    And that's it! You will notice a significant throughput increase, specially for large contents.

    See this example:


    public class FileResponse



        public String Filename { get; set; }

        [MessageBodyMember]    public Byte[] Contents { get; set; }



    public interface IFileService


    OperationContract]    FileResponse GetFile(String filename);


    /* client and server */



    binding name="WsHttpMtomBinding" messageEncoding="Mtom" />



    /* server only */ 


    service behaviorConfiguration="Behavior" name="FileService">

            <endpoint binding="wsHttpBinding" bindingConfiguration="WsHttpMtomBinding" contract="IFileService">



    /* client only */ 


        <endpoint address="http://localhost:8001/FileService.svc" binding="wsHttpBinding" bindingConfiguration="WsHttpMtomBinding" contract="IFileService" name="IFileService"/>



  • Interface Inheritance

    I am normally against having an interface inherit from another one, but there's a situation where I am in favor of it: web service interfaces!

    The reason is that we can write code like this:

    using (ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>())


        using (IMyService svc = factory.CreateChannel())




    instead of:

    using (ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>())


        IMyService svc = factory.CreateChannel();

        using (svc as IDisposable)


            //the generated proxy does implement IDisposable!



    I think this leads to more elegant code. I know there's a problem with using a ChannelFactory like this, and I will come back to it in a future post! :-)