Vibrant discussion about CSLA .NET and using the framework to build great business applications.
With SL3 we get binary encoding of the WCF for silverlight.
http://www.silverlight.net/learn/videos/silverlight-videos/hdi-silverlight-3-binary-encoding/
In the past I've used the WCF compression example provided in the CslaLight Samples. Now that we have binary encoding, does this make that model obsolete??
Has anyone got experience doing benchmarking on comparing the two?
Looks like this is already being discussed on another thread. My appologies for the duped post. I'll post any questions on this thread instead:
http://forums.lhotka.net/forums/thread/34880.aspx
Using binary XML in CSLA .NET is a multi-level proposition.
CSLA .NET does some serialization internally, and CSLA .NET 3.8 now defaults to using binary XML.
The MobileFormatter does its own serialization as well, and so in 3.8 that now defaults to using binary XML too - so you get that automatically.
Those streams of data you compress (in the compression example) are the serialized data going to/from MobileFormatter - so in 3.8 you'll be compressing the binary XML.
The other level where this matters is in the WCF data transfer itself. You control this based on how you configure your WCF endpoint and client. The thing is, the data portal service contract transfers byte arrays, not object graphs. So the WCF serialization is really only working with already-serialized and maybe already-compressed data.
However, there's a lot of value in using binary XML at the WCF level, because with text XML those byte arrays (binary data) must be converted into text to be valid XML. That almost doubles the size of the byte stream! Using binary XML should avoid that binary-to-text conversion and therefore should avoid the doubling of the byte stream size.
Yes, XML sometimes really sucks.
So in CSLA 3.8 you already get binary XML. I suggest you continue to use compression, and that you also configure WCF to use binary XML. That gives you the smallest data at all threee levels available.
Rocky
I see that on the server side the UseBinaryXml can be configured with an AppSetting key CslaUseBinaryXml. But how might I configure the UseBinaryXml property of the MobileFormatter in Silverlight? I was hoping to do some quick benchmarking. I see that the MobileFormatter class is sealed, and I can't access that static property.
In the code behind App.xaml, right where you’d configure the data portal to run locally, you can set a property on MobileFormatter (I think) to do the same thing. The 3.8 change log has info on this.
If you have trouble finding it let me know and I’ll help – I appreciate you taking the time to do some comparative testing!
Yes, but unfortunately the static UseBinaryXml property on the MobileFormatter is inaccessible because the class is sealed. For doing my benchmarking I'll just create a csla build where that class isn't sealed. Unless you can't think of any other way to change that value, but I don't seem to see one.
It is a public static though. You should be able to just do this in app.xaml.cs:
Csla.Serialization.Mobile.MobileFormatter.UseBinaryXml = true;
No need to alter CSLA at all.
sorry, you're right! The property wasn't showing up to me before because I had forgotten to update the csla reference from 3.7 to 3.8 at that time. I thought that was kind of odd...I started assuming it was because the SL runtime handled sealed accesibility differently or something lol.
I'll be sure to post any results I come up with.
I made a few steps further to getting a benchmark app setup today. But I ran into a roadblock that I was needing help with.When switching UseBinaryXml to false, I get the following error when trying to deserialize.
There was an error deserializing the object of type System.Collections.Generic.List`1[[Csla.Serialization.Mobile.SerializationInfo, Csla, Version=3.8.0.0, Culture=neutral, PublicKeyToken=93be5fdc093e4c30]]. The input source is not correctly formatted.
System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type System.Collections.Generic.List`1[[Csla.Serialization.Mobile.SerializationInfo, Csla, Version=3.8.0.0, Culture=neutral, PublicKeyToken=93be5fdc093e4c30]]. The input source is not correctly formatted. ---> System.Xml.XmlException: The input source is not correctly formatted.\r\n at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)\r\n at System.Xml.XmlBufferReader.ReadValue(XmlBinaryNodeType nodeType, ValueHandle value)\r\n at System.Xml.XmlBinaryReader.ReadNode()\r\n at System.Xml.XmlBinaryReader.Read()\r\n at System.Xml.XmlBaseReader.IsStartElement()\r\n at System.Xml.XmlBaseReader.IsStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri)\r\n at System.Runtime.Serialization.XmlReaderDelegator.IsStartElement(XmlDictionaryString localname, XmlDictionaryString ns)\r\n at System.Runtime.Serializa
tion.XmlObjectSerializer.IsRootElement(XmlReaderDelegator reader, DataContract contract, XmlDictionaryString name, XmlDictionaryString ns)\r\n at System.Runtime.Serialization.DataContractSerializer.InternalIsStartObject(XmlReaderDelegator reader)\r\n at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName)\r\n at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName)\r\n --- End of inner exception stack trace ---\r\n at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName)\r\n at System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlReader reader)\r\n at Csla.Serialization.Mobile.MobileFormatter.Deserialize(XmlReader reader) in C:\\Projects\\Local\\csla3.8.0beta\\cslacs\\Csla\\Serialization\\Mobile\\MobileFormatter.cs:line 258\r\n at Csla.Serialization.Mobile.Mobil
eFormatter.Deserialize(Stream serializationStream) in C:\\Projects\\Local\\csla3.8.0beta\\cslacs\\Csla\\Serialization\\Mobile\\MobileFormatter.cs:line 229\r\n at Csla.Serialization.Mobile.MobileFormatter.Deserialize(Byte[] data) in C:\\Projects\\Local\\csla3.8.0beta\\cslacs\\Csla\\Serialization\\Mobile\\MobileFormatter.cs:line 378\r\n at Csla.Server.Hosts.Silverlight.WcfPortal.GetCriteria(Byte[] criteriaData) in C:\\Projects\\Local\\csla3.8.0beta\\cslacs\\Csla\\Server\\Hosts\\Silverlight\\WcfPortal.cs:line 302\r\n at Csla.Server.Hosts.Silverlight.WcfPortal.Fetch(CriteriaRequest request) in C:\\Projects\\Local\\csla3.8.0beta\\cslacs\\Csla\\Server\\Hosts\\Silverlight\\WcfPortal.cs:line 126"
The error occurs inside the MobileFormatter where ReadObject is called on the DataContractSerializer. It seems that even thought I've turned off UseBinaryXml, the reader that is trying to be used is still of type System.Xml.XmlBinaryReader, which I suppose explains why an error gets thrown....
Is this a bug with regards to this configurable?
This sounds like a bug – did you find specifically where the code is wrong?
The bug isn't an obvious one. ReadObject() is called in Deserialize(), and that gets its reader from GetXmlReader(), which is the central method that returns either a normal or binary reader.
Are you sure you have your server and client side configurations both set properly?
Sorry for the alarm -- you're absolutely right in asking that. I had forgotten about the need to configure the server web.config. Adding the appkey on the server solves the problem.
With this in mind, I suppose it's not easily possible to create an application with some objects using BinaryEncoding and some not?
The data portal uses a central configuration…
Well it isn't hard. Here is an example for SL for anyone interested:
1) Add a new customBinding to both the server/client
2) Change the endpoint to use the new binding name and configuration.
3) The maxRecieved/buffer etc sizes are in different spots than in the basic HTTP bindings and are different on the Client than on the server. But it only took 5 mins which was less time than I spent looking for an example.
In ServiceReferences.ClientConfig:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IWcfPortal" maxBufferSize="80000000"
maxReceivedMessageSize="80000000" receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00">
</binding>
</basicHttpBinding>
<customBinding>
<binding name="BinaryBinding_IWcfPortal">
<binaryMessageEncoding/>
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
</customBinding>
</bindings>
<client>
<!--<endpoint address="http://localhost:2555/WcfPortal.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IWcfPortal"
contract="Csla.WcfPortal.IWcfPortal" name="BasicHttpBinding_IWcfPortal" />-->
<endpoint address="http://localhost:2555/WcfPortal.svc" binding="customBinding" bindingConfiguration="BinaryBinding_IWcfPortal"
contract="Csla.WcfPortal.IWcfPortal" name="BinaryBinding_IWcfPortal" />
</client>
</system.serviceModel>
</configuration>
In web.config in WCF project:
<binding name="BasicHttpBinding_IWcfPortal" maxBufferSize="80000000" maxReceivedMessageSize="80000000" receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00">
<readerQuotas maxBytesPerRead="80000000" maxArrayLength="80000000" maxStringContentLength="80000000"/>
<binding name="BinaryBinding_IWcfPortal" receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00" >
<binaryMessageEncoding maxReadPoolSize="2147483647" maxSessionSize="2147483647" maxWritePoolSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="5242880" maxArrayLength="200000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binaryMessageEncoding>
<httpTransport maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"/>
<services>
<!--<service behaviorConfiguration="WcfPortalBehavior" name="Csla.Server.Hosts.Silverlight.WcfPortal">-->
<service behaviorConfiguration="WcfPortalBehavior" name="AlexanderGracie.Library.Compression.CompressedHost">
<endpoint address="" binding="customBinding" contract="Csla.Server.Hosts.Silverlight.IWcfPortal" bindingConfiguration="BinaryBinding_IWcfPortal">
<!--<endpoint address="" binding="basicHttpBinding" contract="Csla.Server.Hosts.Silverlight.IWcfPortal" bindingConfiguration="BasicHttpBinding_IWcfPortal">-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
</services>
From: Jack [mailto:cslanet@lhotka.net] Sent: October-27-09 1:47 PM To: jaddington@alexandergracie.com Subject: Re: [CSLA .NET] Silverlight Compression (which is better binary WCF or CslaLight example?)
Is there an example in any of the samples of using binary XML in WCF ? Thanks jack