0

We are currently using WCF for our transfer between our clients and servers. We are using HttpTransportBinding, with BinaryMessageEncoding. The back end is .NET, and the front end is Xamarin (iOS, Android, Windows 10) and Silverlight. We are looking at different options for transfer. Of course there are REST, and Web Sockets as well, but my question pertains to serialization - not the actual protocol. I am however, looking at all of our options for reducing the bandwidth of transfer.

The ultimate aim is to use binary serialization that only transfers minimal data in order for the DataContract serialization to work correctly. The transfer does not need to be human readable, and this is why we are not using Json. I am open to looking at other kinds of serialization, or other DataContractSerializers that will do the job, but what I'm struggling with right now, is that WCF sends way more data across the wire than is actually necessary. If I look at the data in Fiddler, I can see that it is sending DataMembers that are null or empty, XML namespaces that are totally irrelevant, and so on.

Here is a typical piece of transfer: enter image description here

Here you can see that I have tried to stop the DataContractSerializer from sending these things across the wire at the attribute level, but the DataContractSerializer ignores my pleas:

    [DataMember(IsRequired = false)]
    bool IsPrimaryKeyOnly { get; set; }

    [DataMember(IsRequired = false)]
    ErrorDictionary ErrorDetails { get; set; }

    [DataMember(IsRequired =false)]
    bool IgnoreWarnings { get; set; }


    [System.Runtime.Serialization.DataContractAttribute(IsReference = true, Namespace = "")]
    [System.SerializableAttribute()]
    public class AssetClass : Adapt.Model.RecordBase, Adapt.Model.IRecord
    {
    }

Is there anything I can do to get the DataContractSerializer to honour my requests? Is there a more efficient DataContractSerializer that is compatible with Xamarin? Any other tricks to reduce WCF verbosity? Am I doing something wrong here in the way I am declaring my attributes, or am I wrong in thinking that the serializer should be smart enough not to include default values?

What is so frustrating about this is that other than this problem, WCF is a very good technology when you know that all the consumers of the service are going to be Microsoft based. On the face of it, it just seems as though Microsoft stopped bothering to improve WCF and its subsequent parts such as DataContractSerialization. I'd rather not wholesale replace the technology. I'd rather just fix the problem with the verbosity.

Please save alternative technology suggestions for comments only.

Christian Findlay
  • 6,770
  • 5
  • 51
  • 103
  • With no warranties as to the applicability of the following to your specific situation (never used BinaryMessageEncoding, we stick with JSON), here are 2 things which you could look into: `[DataMember(EmitDefaultValue = false)]` and Dynamic Content Compression in IIS. – Kirill Shlenskiy Oct 26 '17 at 02:06
  • Thanks. Yes, we already use Dynamic Content Compression in IIS. This is a very important thing to get right. It's actually quite hard to set up on the server, but once it's done once, bandwidth does go down a lot. – Christian Findlay Oct 26 '17 at 02:27
  • You may be on to something with EmitDefaultValue. The doco says "It is occasionally desirable to omit a data member from the serialized data when it is set to its default value. To do this, set the EmitDefaultValue property to false (it is true by default)." . The word "Emit" threw me. It appears that it is a misspelling, and really should be "OmitDefaultValue". – Christian Findlay Oct 26 '17 at 02:36
  • I tried this, and on the face of it, it made no difference... – Christian Findlay Oct 26 '17 at 23:18

1 Answers1

0

Partial answer: https://bkiener.wordpress.com/2010/05/04/optimize-data-contracts-for-better-wcf-performance/

One thing that can be done is to reduce the names of DataContracts and Properties by specifying their Name in the attribute itself. So, a property named "ReallyLongPropertyNameThatEatsBandwidth" could be aliased as "a". I did some basic tests with this and one of our calls went down from 188k to 168k. This still doesn't explain all the other junk in the transfer, but it helps.

Christian Findlay
  • 6,770
  • 5
  • 51
  • 103