none
How to enable gzip compression in self-hosted WCF data service? RRS feed

  • Question

  • How to do it?

    I have found only IIS gzip support so far.

    Our WCF data services use

    • SQL Server 2014/2016/2017
    • Entity Framework 6.2
    • Microsoft.OData.EntityFrameworkProvider
    •   1.0.0-beta2
    •     Is there something newer or is it already dead?
    • .NET Framework 4.6.2
    • Self-hosting in Windows service process

    My attempts with WebHttpBinding derived binding using GZipMessageEncodingBindingElement:

        /// <summary>
        /// Extends <see cref="WebHttpBinding"/> with GZip compression
        /// </summary>
        public class GZipWebHttpBinding :
            WebHttpBinding
        {
            #region Init
    
            public GZipWebHttpBinding()
            { }
    
            public GZipWebHttpBinding(string configurationName)
                : base(configurationName)
            { }
    
            public GZipWebHttpBinding(WebHttpSecurityMode securityMode) :
                base(securityMode)
            { }
    
            #endregion
    
            public override BindingElementCollection CreateBindingElements()
            {
                var elements = base.CreateBindingElements();
                var messageEncoding = elements.
                    OfType<WebMessageEncodingBindingElement>().
                    First();
                var index = elements.IndexOf(messageEncoding);
                elements[index] = new GZipMessageEncodingBindingElement(messageEncoding);
                return elements;
            }
        }

    fail with:

    System.InvalidOperationException: The operation 'ProcessRequestForMessage' could not be loaded because it has a parameter or return type of type System.ServiceModel.Channels.Message or a type that has MessageContractAttribute and other parameters of different types. When using System.ServiceModel.Channels.Message or types with MessageContractAttribute, the method must not use any other types of parameters. at System.ServiceModel.Dispatcher.OperationFormatter.Validate(OperationDescription operation, Boolean isRpc, Boolean isEncoded) at System.ServiceModel.Dispatcher.OperationFormatter..ctor(OperationDescription description, Boolean isRpc, Boolean isEncoded) at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter..ctor(OperationDescription description, DataContractFormatAttribute dataContractFormatAttribute, DataContractSerializerOperationBehavior serializerFactory) at System.ServiceModel.Description.DataContractSerializerOperationBehavior.GetFormatter(OperationDescription operation, Boolean& formatRequest, Boolean& formatReply, Boolean isProxy) at System.ServiceModel.Description.DataContractSerializerOperationBehavior.System.ServiceModel.Description.IOperationBehavior.ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch) at System.ServiceModel.Description.DispatcherBuilder.BindOperations(ContractDescription contract, ClientRuntime proxy, DispatchRuntime dispatch) at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) at System.ServiceModel.ServiceHostBase.InitializeRuntime() at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at Epos.DataModel.DataServices.EntityFramework.DataServices.Init[TService,TContext](ILogger log, String name)

    What is the proper solution to enable gzip compression in this scenario to optimize data transfer?

    Thank you

    Marek Istvanek

    Monday, February 25, 2019 3:59 PM