WCF Problem with CustomBinding and GZip

WCF Problem with CustomBinding and GZip

Old forum URL: forums.lhotka.net/forums/t/12871.aspx


inflexible posted on Friday, April 24, 2015

Hi,

I have to migrate a Silverlight application to WPF and now I have a problem with the WCF configuration. I need a way to compress the data. In Silverlight I did this with the CompressedHost / CompressedProxy and SharpZipLib.

WCF 4.5 supports GZip compression without third party libraries. So I wanted to use this feature. But the configuration with CustomBinding has not been working. I believe that CSLA does not use my own binding, but I don't know how to bring it.

The WCF error message is: 
Content Type "application/soap+xml; charset=utf-8"  was sent to a service expecting "application/soap+msbin1+gzip". The client and service bindings may be mismatched. 

 

My server configuration (web.config):
Note: The commented part (wsHttpBinding) would work, but without compression. 

<configuration>
    <appSettings>
      <add key="CslaAuthentication" value="Custom" />
      <add key="DalManagerType" value="Csla.Server.Hosts.WcfPortal,PAPMS.ProductLib.Business" />
    </appSettings>
    <system.serviceModel> 
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
        <services>
            <service name="Csla.Server.Hosts.WcfPortal" behaviorConfiguration="returnFaults">
                <endpoint binding="customBinding" bindingConfiguration="CustomBinding_IWcfPortal" contract="Csla.Server.Hosts.IWcfPortal" />
                <!--<endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_IWcfPortal" contract="Csla.Server.Hosts.IWcfPortal" />-->
            </service>
        </services>
        <bindings>
            <customBinding>
                <binding name="CustomBinding_IWcfPortal">
                    <binaryMessageEncoding compressionFormat="GZip"/>
                    <httpTransport decompressionEnabled="true" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
                </binding>
            </customBinding>
            <!--<wsHttpBinding>
                <binding name="wsHttpBinding_IWcfPortal" maxReceivedMessageSize="2147483647" >
                     <readerQuotas maxBytesPerRead="2147483647" maxArrayLength="2147483647" maxStringContentLength="2147483647" maxNameTableCharCount="2147483647" maxDepth="2147483647" />
                </binding>
           </wsHttpBinding>-->
       </bindings>
       <behaviors>
           <serviceBehaviors>
               <behavior name="returnFaults">
                   <serviceDebug includeExceptionDetailInFaults="true" />
                   <serviceMetadata httpGetEnabled="true" />
               </behavior>
           </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
    <system.web>
        <compilation debug="true" targetFramework="4.5" />
    </system.web>
</configuration>

 

My client configuration (app.config):

<configuration>
    <appSettings>
         <add key="CslaDataPortalProxy" value="Csla.DataPortalClient.WcfProxy, Csla" />
         <add key="CslaDataPortalUrl" value="http://localhost/PAPMS.WcfServer/WcfPortal.svc" />  
    </appSettings>
    <system.serviceModel>
        <client>
            <endpoint binding="customBinding" address="http://localhost/PAPMS.WcfServer/WcfPortal.svc" bindingConfiguration="CustomBinding_IWcfPortal" contract="Csla.Server.Hosts.IWcfPortal" name="CustomBinding_IWcfPortal" />
       </client>
       <bindings>
           <customBinding>
                 <binding name="CustomBinding_IWcfPortal">
                     <binaryMessageEncoding compressionFormat="GZip" />
                     <httpTransport decompressionEnabled="true" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
                 </binding>
            </customBinding>
        </bindings>
    </system.serviceModel>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>

 

As a side note, I use CSLA 4.5.501.

I would be very happy if someone could help me. Thank you in advance!

Best Regards, Adrian

JonnyBee replied on Saturday, April 25, 2015

Hi,

On the client you must remove CslaDataPortalUrl setting and keep the CslaDataPortalProxy setting. 
When CslaDataPortalUrl setting exists, CSLA will use a default configuration for binding (in code). 

In order to use read all settings (binding etc) from app.config add configuration for an endpoint named WcfDataPortal

You may configure another endpoint name in code - but just simpler to use the default WcfDataPortal. 

Here is code from Csla.DataPortalClient.WcfProxy


private static string _defaultEndPoint = "WcfDataPortal"; protected virtual ChannelFactory<IWcfPortal> GetChannelFactory() {   // if dataportal url is specified use this with default wsHttBinding   if (!string.IsNullOrEmpty(ApplicationContext.DataPortalUrlString))   {     var binding = new WSHttpBinding()     {        MaxReceivedMessageSize = int.MaxValue,        ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()        {         MaxBytesPerRead = int.MaxValue,         MaxDepth = int.MaxValue,         MaxArrayLength = int.MaxValue,         MaxStringContentLength = int.MaxValue,         MaxNameTableCharCount = int.MaxValue       }     };     return new ChannelFactory<IWcfPortal>(binding, new EndpointAddress(ApplicationContext.DataPortalUrl));   }   // else return a channelfactory that uses the endpoint configuration in app.config/web.config   return new ChannelFactory<IWcfPortal>(EndPoint);
}

inflexible replied on Monday, April 27, 2015

Hi,

Thanks for your answer. In addition to your instructions, I had to change the client contract to WcfPortal.IWcfPortal.

<client>
     <endpoint binding="customBinding" address="http://localhost/PAPMS.WcfServer/WcfPortal.svc" bindingConfiguration="BinaryCompressionBinding" contract="WcfPortal.IWcfPortal" name="WcfDataPortal" />
</client>

The data is finally loaded via the CustomBinding. BUT the data is not compressed. When I look at the messages in Fiddler, the response has always the same size, regardless of whether I set the compression to None / GZip / Deflate. The response content-type is always application/soap+msbin1 instead of application/soap+msbin1+gzip

Do you have any idea what I could do to make the server compresses the data? The server runs in an IIS 7.5 and the compression is turned on there.

JonnyBee replied on Tuesday, April 28, 2015

Hi,

1. Make sure that Fiddler's "AutoDecode" and Transforms are turned off if you really want to be sure you're looking at the raw stuff.

2. Make sure that the servere actually reads it's configuration from web.config. 

I have never configured CSLA DataPortal with Compression so these are just assumptions on where I would start. 


inflexible replied on Tuesday, April 28, 2015

Hi,

Thanks! It was the "AutoDecode"... Now it works as desired. Thank you for your help!

Copyright (c) Marimer LLC