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
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);
}
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.
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.
Hi,
Thanks! It was the "AutoDecode"... Now it works as desired. Thank you for your help!
Copyright (c) Marimer LLC