CSLA ObservableBindingList<T> causes System.Xml.XmlException due to auto property

CSLA ObservableBindingList<T> causes System.Xml.XmlException due to auto property

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


Sevans posted on Monday, July 11, 2011

I think I came across an issue in Csla.Core.ObservableBindingList<T>.  Any derived business objects (like anything derived from ReadOnlyListBase<>) throws a System.Xml.XmlException when it's serialized across the wire in WCF.  It seems to be due to the auto properties of AllowEdit, AllowNew, and AllowRemove.  Since auto properties get a "odd" backing field that contains the < and > symbols, when they're serialized as XML they silently fail.  Changing these properties to have a backing field with a "normal" name makes the exception disappear.

While it doesn't seem to have a major performance issue, it's still quite annoying to litter up the Output window when debugging.

I'm wondering if this is an issue that people just ignore since everything still works, or is there's a configuration attribute we might have missed in setting up our WcfPortal?  I'd be happy to share our WCF configuration information if it'd help.

RockfordLhotka replied on Tuesday, July 12, 2011

This is using the data portal, or directly trying to serialize the objects through WCF? Direct serialization through WCF won't work - that is just not a supported scenario (http://www.lhotka.net/cslanet/faq/DataPortalFaq.ashx).

And is this pure .NET, or is it a Silverlight client?

In pure .NET, the BinaryFormatter or NetDataContractSerializer must be used. The NDCS is used by the data portal's WCF channel.

With a Silverlight client, the serialization is handled by the MobileFormatter, which is part of CSLA .NET itself. This is a whole other process.

Sevans replied on Tuesday, July 12, 2011

This is using the DataPortal over WCF.  We're just doing a DataPortal.BeginFetch() on the Silverlight client to retrieve the full list.  This is using CSLA 4.1, targeting .NET 4 and SL4 (if it has an impact...)

Like I mentioned, this is a Silverlight client, but I'm not 100% sure it's just Silverlight causing it.

We do have the WCF configuration set up to use binary message encoding over HTTP, so the binary formatter is likely being used.  We did extend the WcfPortal for some additional logging, but the exception is being thrown before that point.

The exception is thrown in Csla.DataPortalClient.WcfProxy.Fetch(Type, object, DataPortalContext), specifically the line `response = svr.Fetch(new FetchRequest(objectType, criteria, context));` (around line 148 in that file).  The stack trace for it is below (bolded the line it's caught at).  According to the Visual Studio threads debugger, it's on a thread under the w3wp.exe process; so it appears to be on the server side serialization.  What other information would be useful to help figure this out?

     System.Xml.dll!System.Xml.XmlConvert.VerifyNCName(string name, System.Xml.ExceptionType exceptionType) + 0xb5 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.IsValidNCName(string name) + 0x27 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.EncodeLocalName(string localName = "<AllowEdit>k__BackingField") + 0x1d bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper.ImportDataMembers() + 0x2e1 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper.ClassDataContractCriticalHelper(System.Type type) + 0x10d bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContract(System.Type type) + 0x1f bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.GetSharedTypeContract(System.Type type) + 0x60 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.CollectionDataContract(System.Type type, System.Runtime.Serialization.CollectionKind kind, System.Type itemType, System.Reflection.MethodInfo getEnumeratorMethod, System.Reflection.MethodInfo addMethod, System.Reflection.ConstructorInfo constructor, bool isConstructorCheckRequired) + 0x48 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.IsCollectionOrTryCreate(System.Type type, bool tryCreate, out System.Runtime.Serialization.DataContract dataContract = null, out System.Type itemType, bool constructorRequired) + 0x935 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(int id = 63, System.RuntimeTypeHandle typeHandle, System.Type type = {Name = "ObservableBindingList`1" FullName = "Csla.Core.ObservableBindingList`1[[FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfo, FAC.Phoebe.Billing.BLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}) + 0x149 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(int id, System.RuntimeTypeHandle typeHandle, System.Type type) + 0x57 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper.ClassDataContractCriticalHelper(System.Type type = {Name = "ReadOnlyObservableBindingList`1" FullName = "Csla.Core.ReadOnlyObservableBindingList`1[[FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfo, FAC.Phoebe.Billing.BLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}) + 0x251 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContract(System.Type type) + 0x1f bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.GetSharedTypeContract(System.Type type) + 0x60 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.CollectionDataContract(System.Type type, System.Runtime.Serialization.CollectionKind kind, System.Type itemType, System.Reflection.MethodInfo getEnumeratorMethod, System.Reflection.MethodInfo addMethod, System.Reflection.ConstructorInfo constructor, bool isConstructorCheckRequired) + 0x48 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.IsCollectionOrTryCreate(System.Type type, bool tryCreate, out System.Runtime.Serialization.DataContract dataContract = null, out System.Type itemType, bool constructorRequired) + 0x935 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(int id = 62, System.RuntimeTypeHandle typeHandle, System.Type type = {Name = "ReadOnlyObservableBindingList`1" FullName = "Csla.Core.ReadOnlyObservableBindingList`1[[FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfo, FAC.Phoebe.Billing.BLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}) + 0x149 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(int id, System.RuntimeTypeHandle typeHandle, System.Type type) + 0x57 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper.ClassDataContractCriticalHelper(System.Type type = {Name = "ReadOnlyListBase`2" FullName = "Csla.ReadOnlyListBase`2[[FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfoList, FAC.Phoebe.Billing.BLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfo, FAC.Phoebe.Billing.BLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}) + 0x251 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContract(System.Type type) + 0x1f bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.GetSharedTypeContract(System.Type type) + 0x60 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.CollectionDataContract(System.Type type, System.Runtime.Serialization.CollectionKind kind, System.Type itemType, System.Reflection.MethodInfo getEnumeratorMethod, System.Reflection.MethodInfo addMethod, System.Reflection.ConstructorInfo constructor, bool isConstructorCheckRequired) + 0x48 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.IsCollectionOrTryCreate(System.Type type, bool tryCreate, out System.Runtime.Serialization.DataContract dataContract = null, out System.Type itemType, bool constructorRequired) + 0x935 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(int id = 61, System.RuntimeTypeHandle typeHandle, System.Type type = {Name = "ReadOnlyListBase`2" FullName = "Csla.ReadOnlyListBase`2[[FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfoList, FAC.Phoebe.Billing.BLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfo, FAC.Phoebe.Billing.BLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}) + 0x149 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(int id, System.RuntimeTypeHandle typeHandle, System.Type type) + 0x57 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper.ClassDataContractCriticalHelper(System.Type type = {Name = "ContactInfoList" FullName = "FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfoList"}) + 0x251 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContract(System.Type type) + 0x1f bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.GetSharedTypeContract(System.Type type) + 0x60 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.CollectionDataContract(System.Type type, System.Runtime.Serialization.CollectionKind kind, System.Type itemType, System.Reflection.MethodInfo getEnumeratorMethod, System.Reflection.MethodInfo addMethod, System.Reflection.ConstructorInfo constructor, bool isConstructorCheckRequired) + 0x48 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.CollectionDataContract.IsCollectionOrTryCreate(System.Type type, bool tryCreate, out System.Runtime.Serialization.DataContract dataContract = null, out System.Type itemType, bool constructorRequired) + 0x935 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(int id = 60, System.RuntimeTypeHandle typeHandle, System.Type type = {Name = "ContactInfoList" FullName = "FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfoList"}) + 0x149 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(int id, System.RuntimeTypeHandle typeHandle, System.Type type) + 0x57 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerContext.GetDataContract(System.RuntimeTypeHandle typeHandle, System.Type type) + 0x66 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.GetDataContract(System.RuntimeTypeHandle typeHandle, System.Type type) + 0x76 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserializeInSharedTypeMode(System.Runtime.Serialization.XmlReaderDelegator xmlReader = {System.Runtime.Serialization.XmlReaderDelegator}, int declaredTypeID = 11, System.Type declaredType = {Name = "Object" FullName = "System.Object"}, string name, string ns) + 0xb4 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(System.Runtime.Serialization.XmlReaderDelegator xmlReader, int declaredTypeID, System.RuntimeTypeHandle declaredTypeHandle, string name, string ns) + 0xa0 bytes   
     [Lightweight Function]   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ReadXmlValue(System.Runtime.Serialization.XmlReaderDelegator xmlReader = {System.Runtime.Serialization.XmlReaderDelegator}, System.Runtime.Serialization.XmlObjectSerializerReadContext context) + 0x30 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(System.Runtime.Serialization.DataContract dataContract, System.Runtime.Serialization.XmlReaderDelegator reader) + 0x13 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserializeInSharedTypeMode(System.Runtime.Serialization.XmlReaderDelegator xmlReader, int declaredTypeID, System.Type declaredType, string name, string ns) + 0x1cb bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(System.Runtime.Serialization.XmlReaderDelegator xmlReader, int declaredTypeID, System.RuntimeTypeHandle declaredTypeHandle, string name, string ns) + 0xa0 bytes   
     [Lightweight Function]   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ReadXmlValue(System.Runtime.Serialization.XmlReaderDelegator xmlReader = {System.Runtime.Serialization.XmlReaderDelegator}, System.Runtime.Serialization.XmlObjectSerializerReadContext context) + 0x30 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(System.Runtime.Serialization.DataContract dataContract, System.Runtime.Serialization.XmlReaderDelegator reader) + 0x13 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserializeInSharedTypeMode(System.Runtime.Serialization.XmlReaderDelegator xmlReader, int declaredTypeID, System.Type declaredType, string name, string ns) + 0x1cb bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Type declaredType, string name, string ns) + 0x96 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.NetDataContractSerializer.InternalReadObject(System.Runtime.Serialization.XmlReaderDelegator xmlReader, bool verifyObjectName) + 0x7d bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject(System.Runtime.Serialization.XmlReaderDelegator reader, bool verifyObjectName, System.Runtime.Serialization.DataContractResolver dataContractResolver) + 0x10 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(System.Runtime.Serialization.XmlReaderDelegator reader, bool verifyObjectName, System.Runtime.Serialization.DataContractResolver dataContractResolver) + 0x63 bytes   
     System.Runtime.Serialization.dll!System.Runtime.Serialization.NetDataContractSerializer.ReadObject(System.Xml.XmlDictionaryReader reader, bool verifyObjectName) + 0x2f bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(System.Xml.XmlDictionaryReader reader, System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo part = {System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo}, bool isRequest) + 0x38 bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameter(System.Xml.XmlDictionaryReader reader, System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo part, bool isRequest) + 0x2a bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(System.Xml.XmlDictionaryReader reader = {System.Xml.XmlReader.XmlReaderDebuggerDisplayProxy}, System.ServiceModel.Channels.MessageVersion version, string action, System.ServiceModel.Description.MessageDescription messageDescription, object[] parameters = {object[0]}, bool isRequest = false) + 0xac bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(System.ServiceModel.Channels.Message message = {System.ServiceModel.Channels.BufferedMessage}, object[] parameters, bool isRequest) + 0xae bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.OperationFormatter.DeserializeReply(System.ServiceModel.Channels.Message message, object[] parameters) + 0xd9 bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ref System.ServiceModel.Dispatcher.ProxyRpc rpc = {System.ServiceModel.Dispatcher.ProxyRpc}) + 0x45 bytes   
     System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.HandleReply(System.ServiceModel.Dispatcher.ProxyOperationRuntime operation = {System.ServiceModel.Dispatcher.ProxyOperationRuntime}, ref System.ServiceModel.Dispatcher.ProxyRpc rpc = {System.ServiceModel.Dispatcher.ProxyRpc}) + 0x102 bytes   
     System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.Call(string action, bool oneway, System.ServiceModel.Dispatcher.ProxyOperationRuntime operation, object[] ins, object[] outs, System.TimeSpan timeout) + 0x34c bytes   
     System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(System.Runtime.Remoting.Messaging.IMethodCallMessage methodCall = {System.Runtime.Remoting.Messaging.Message}, System.ServiceModel.Dispatcher.ProxyOperationRuntime operation = {System.ServiceModel.Dispatcher.ProxyOperationRuntime}) + 0x59 bytes   
     System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannelProxy.Invoke(System.Runtime.Remoting.Messaging.IMessage message = {System.Runtime.Remoting.Messaging.Message}) + 0x65 bytes   
     mscorlib.dll!System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(ref System.Runtime.Remoting.Proxies.MessageData msgData, int type = 1) + 0xee bytes   
>    Csla.dll!Csla.DataPortalClient.WcfProxy.Fetch(System.Type objectType = {Name = "ContactInfoList" FullName = "FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfoList"}, object criteria = {Csla.Server.EmptyCriteria}, Csla.Server.DataPortalContext context = {Csla.Server.DataPortalContext}) Line 148 + 0x2b bytes    C#
     Csla.dll!Csla.DataPortal.Fetch(System.Type objectType = {Name = "ContactInfoList" FullName = "FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfoList"}, object criteria = {Csla.Server.EmptyCriteria}) Line 215 + 0x12 bytes    C#
     Csla.dll!Csla.DataPortal.Fetch(System.Type objectType = {Name = "ContactInfoList" FullName = "FAC.Phoebe.Billing.BLL.ReadOnly.ContactInfoList"}) Line 186 + 0xe bytes    C#
     Csla.dll!Csla.Server.Hosts.Silverlight.SilverlightRequestProcessor.Fetch(Csla.Server.Hosts.Silverlight.SilverlightCriteriaRequest request = {Csla.Server.Hosts.Silverlight.SilverlightCriteriaRequest}) Line 144 + 0x9 bytes    C#
     Csla.dll!Csla.Server.Hosts.Silverlight.WcfPortal.Fetch(Csla.Server.Hosts.Silverlight.CriteriaRequest request = {Csla.Server.Hosts.Silverlight.CriteriaRequest}) Line 102 + 0xe bytes    C#
     [Lightweight Function]   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(object instance, object[] inputs, out object[] outputs) + 0x33f bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(ref System.ServiceModel.Dispatcher.MessageRpc rpc = {System.ServiceModel.Dispatcher.MessageRpc}) + 0x137 bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(ref System.ServiceModel.Dispatcher.MessageRpc rpc = {System.ServiceModel.Dispatcher.MessageRpc}) + 0x5e bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(ref System.ServiceModel.Dispatcher.MessageRpc rpc) + 0x6c bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(ref System.ServiceModel.Dispatcher.MessageRpc rpc) + 0x89 bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(ref System.ServiceModel.Dispatcher.MessageRpc rpc) + 0x59 bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(ref System.ServiceModel.Dispatcher.MessageRpc rpc) + 0x3b bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(ref System.ServiceModel.Dispatcher.MessageRpc rpc) + 0x4e bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(ref System.ServiceModel.Dispatcher.MessageRpc rpc) + 0x125 bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(ref System.ServiceModel.Dispatcher.MessageRpc rpc) + 0x34 bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.MessageRpc.Process(bool isOperationContextSet = false) + 0xff bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(System.ServiceModel.Channels.RequestContext request = {System.ServiceModel.Activation.HostedHttpContext}, bool cleanThread, System.ServiceModel.OperationContext currentOperationContext) + 0x44b bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(System.ServiceModel.Channels.RequestContext request, System.ServiceModel.OperationContext currentOperationContext) + 0x127 bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(System.IAsyncResult result) + 0x43 bytes   
     System.ServiceModel.dll!System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(System.IAsyncResult result) + 0x44 bytes   
     System.Runtime.DurableInstancing.dll!System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(System.IAsyncResult result) + 0x32 bytes   
     System.Runtime.DurableInstancing.dll!System.Runtime.AsyncResult.Complete(bool completedSynchronously) + 0xfd bytes   
     System.Runtime.DurableInstancing.dll!System.Runtime.InputQueue<System.ServiceModel.Channels.RequestContext>.AsyncQueueReader.Set(System.Runtime.InputQueue<System.ServiceModel.Channels.RequestContext>.Item item) + 0x44 bytes   
     System.Runtime.DurableInstancing.dll!System.Runtime.InputQueue<System.ServiceModel.Channels.RequestContext>.EnqueueAndDispatch(System.Runtime.InputQueue<System.ServiceModel.Channels.RequestContext>.Item item, bool canDispatchOnThisThread) + 0x1aa bytes   
     System.Runtime.DurableInstancing.dll!System.Runtime.InputQueue<System.ServiceModel.Channels.RequestContext>.EnqueueAndDispatch(System.ServiceModel.Channels.RequestContext item, System.Action dequeuedCallback, bool canDispatchOnThisThread) + 0x5e bytes   
     System.ServiceModel.dll!System.ServiceModel.Channels.SingletonChannelAcceptor<System.ServiceModel.Channels.IReplyChannel,System.ServiceModel.Channels.ReplyChannel,System.ServiceModel.Channels.RequestContext>.Enqueue(System.ServiceModel.Channels.RequestContext item, System.Action dequeuedCallback, bool canDispatchOnThisThread) + 0x6b bytes   
     System.ServiceModel.dll!System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(System.ServiceModel.Channels.HttpRequestContext context = {System.ServiceModel.Activation.HostedHttpContext}, System.Action callback) + 0x1b4 bytes   
     System.ServiceModel.Activation.dll!System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(System.ServiceModel.Activation.HostedHttpRequestAsyncResult result) + 0xbe bytes   
     System.ServiceModel.Activation.dll!System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest() + 0x1cf bytes   
     System.ServiceModel.Activation.dll!System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest() + 0x27 bytes   
     System.ServiceModel.Activation.dll!System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(object state) + 0x49 bytes   
     System.Runtime.DurableInstancing.dll!System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* nativeOverlapped) + 0x78 bytes   
     System.Runtime.DurableInstancing.dll!System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(uint error, uint bytesRead, System.Threading.NativeOverlapped* nativeOverlapped) + 0x39 bytes   
     mscorlib.dll!System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) + 0x74 bytes   
     [Native to Managed Transition]   
     [Appdomain Transition]   
     [Native to Managed Transition]   
 

RockfordLhotka replied on Tuesday, July 12, 2011

So you also have a Windows Forms client to this business layer?

It is possible that there's a bug in the bindinglist code that is causing issues with MobileFormatter. I think we have tests for all those types, but because the bindinglist types exist purely for legacy support of Windows Forms, it is possible we missed a test for this type in Silverlight...

RockfordLhotka replied on Tuesday, July 12, 2011

I've added a bug to look into this.

Fwiw, the Silverlight data portal always uses the MobileFormatter, which copies all field values into a DTO graph, and that DTO graph is what's serialized by WCF (by the DataContractSerializer). There is no BinaryFormatter or NetDataContractSerializer on Silverlight - they just don't exist.

I'm somewhat confused as to why your stack trace has no mention of MobileFormatter at all. Nor does it appear to be serializing the DTO graph. It is almost like it is trying to directly serialize the collection - and that should never happen (can't happen actually - because you'd get a serialization exception).

Sevans replied on Tuesday, July 12, 2011

We don't have a WinForms front end, but if I can find a spare moment during this sprint I might try to build one out to see if the problem exists that way too.  We only have a Silverlight front end, that calls a derived WcfPortal hosted in the web application, which handles (de)compression and passes the call to an Application Host service.

The reason (I think) it doesn't mention the mobile formatter is that it's not happening in the Silverlight side of the call.  It's happening on the server side (which is in/behind the Application Host in our set up).  So in our base/Silverlight object we have something like this (in ContactInfoList.cs, which is shared between the .NET and Silverlight projects):

    [Serializable]
    public partial class ContactInfoList : ReadOnlyListBase<ContactInfoListContactInfo>
    {
        public static void GetContacts(EventHandler<DataPortalResult<ContactInfoList>> callback)
        {
            DataPortal.BeginFetch(callback);
        }
    }

Then in the server-side/.NET portion of the class (in ContactInfoList.NET.cs, which exists only in the .NET project) we something like the following:

    public partial class ContactInfoList
    {
        private static IContactRepository GetRepository()
        {
            return OurNamespace.DalFactory.GetManager().GetProvider<IContactRepository>();
        }
 
        private void DataPortal_Fetch()
        {
            this.Populate(GetRepository().GetContacts());
        }
 
        private void Populate(IEnumerable<ContactInfoDTO> data)
        {
            if (data == null)
            {
                return;
            }
 
            IsReadOnly = false;
            var raiseListChangedEvents = RaiseListChangedEvents;
            RaiseListChangedEvents = false;
            foreach (var item in data)
            {
                Add(DataPortal.FetchChild<ContactInfo>(item));
            }
 
            RaiseListChangedEvents = raiseListChangedEvents;
            IsReadOnly = true;
        }
    }

Trying to toss a break point in any of these parts of the class doesn't help find the exception. It is (or at least appears to be) happening on the server side when the DataPortal is building out the result to send back to the client as part of the callback.

And although it shouldn't matter, for the sake of completeness here's the shared code for the ContactInfo class:


    [Serializable]
    public partial class ContactInfo : ReadOnlyBase<ContactInfo>
    {
        public static readonly PropertyInfo<int> FamilyMemberIDProperty = RegisterProperty<int>(c => c.ContactID);
        public int ContactID
        {
            get { return GetProperty(FamilyMemberIDProperty); }
            private set { LoadProperty(FamilyMemberIDProperty, value); }
        }
 
        public static readonly PropertyInfo<int> LocationIDProperty = RegisterProperty<int>(c => c.LocationID);
        public int LocationID
        {
            get { return GetProperty(LocationIDProperty); }
            private set { LoadProperty(LocationIDProperty, value); }
        }
 
        public static readonly PropertyInfo<string> FirstNameProperty = RegisterProperty<string>(c => c.FirstName);
        public string FirstName
        {
            get { return GetProperty(FirstNameProperty); }
            private set { LoadProperty(FirstNameProperty, value); }
        }
 
        public static readonly PropertyInfo<string> MiddleInitialProperty = RegisterProperty<string>(c => c.MiddleInitial);
        public string MiddleInitial
        {
            get { return GetProperty(MiddleInitialProperty); }
            private set { LoadProperty(MiddleInitialProperty, value); }
        }
 
        public static readonly PropertyInfo<string> LastNameProperty = RegisterProperty<string>(c => c.LastName);
        public string LastName
        {
            get { return GetProperty(LastNameProperty); }
            private set { LoadProperty(LastNameProperty, value); }
        }
 
        public static readonly PropertyInfo<string> PhoneProperty = RegisterProperty<string>(c => c.Phone);
        public string Phone
        {
            get { return GetProperty(PhoneProperty); }
            private set { LoadProperty(PhoneProperty, value); }
        }
 
        public static readonly PropertyInfo<string> EMailProperty = RegisterProperty<string>(c => c.EMail);
        public string EMail
        {
            get { return GetProperty(EMailProperty); }
            private set { LoadProperty(EMailProperty, value); }
        }
 
        /// <summary>
        /// E.g John P. Smith
        /// </summary>
        public string FullMiddleLast
        {
            get
            {
                return String.Format("{0} {1}. {2}", FirstName, MiddleInitial, LastName);
            }
        }
 
        /// <summary>
        /// E.g John Smith
        /// </summary>
        public string FirstLast
        {
            get
            {
                return String.Format("{0} {1}", FirstName, LastName);
            }
        }
 
        /// <summary>
        /// E.g John Smith
        /// </summary>
        public string FullName
        {
            get
            {
                return String.Format("{0} {1}", FirstName, LastName);
            }
        }
 
        /// <summary>
        /// E.g Smith, John
        /// </summary>
        public string LastFirst
        {
            get
            {
                return String.Format("{0}, {1}", LastName, FirstName);
            }
        }
    }
and the .NET specific code:

    public partial class ContactInfo
    {
        private void Child_Fetch(ContactInfoDTO data)
        {
            AutoMapper.Mapper.Map(data, this);
        }
    }

 

Again, it may be how we're building out our read-only business objects or using the DataPortal, but this doesn't seem too far off.

RockfordLhotka replied on Tuesday, July 12, 2011

OK, your code isn't using a bindinglist derived base class, so there's no need to look at the Windows Forms angle. I though you were running into issues with a BindingList derived type.

We absolutely have tests and many apps that use ReadOnlyListBase and it works fine (including various sample apps for the ebook series). So there's something different in your situation from normal.

Your class code doesn't look wrong (or complex).

The Silverlight data portal client talks to a Silverlight-specific server data portal endpoint. That server endpoint uses the MobileFormatter for its serialization - it obviously needs to use the same serialization as the client - so now I'm left wondering what is doing the serialization on the server such that the MobileFormatter isn't involved...

Sevans replied on Tuesday, July 12, 2011

I'm not sure if we're referring to the same BindingList, but the inheritance scheme looks to be ContactInfoList -> Csla.ReadOnlyListBase<T,C> -> Csla.Core.ReadOnlyObservableBindingList<C> -> Csla.Core.ObservableBindingList<C>.

Would seeing our WCF configuration in the Silverlight ServiceReferences.ClientConfig, the web application's web.config and/or the application host's web.config be helpful in figuring out the root cause?  Obviously we can just change the code to not use the auto-properties, but trying to hunt this down there are definitely others that are running into that exception.  Being able to find the root cause would help out quite a bit.

RockfordLhotka replied on Tuesday, July 12, 2011

I'm preparing to go on a fishing trip, and won't be able to look at anything for at least a week (no cell coverage or electricity where we're going). This probably also explains why I'm a bit slow following the details of this thread - my primary focus is on making sure we pack everything we need, because there are no stores there either  :)

The MobileFormatter wouldn't encounter this auto property issue, because it relies on the type to implement IMobileObject and serialize the field values into the serialization stream. This is done in the OnGetState and OnSetState methods. You can see those methods in the code near the bottom of the ObservableBindingList class.

The fact that some other serializer is failing seems to pretty clearly imply that somehow the MobileFormatter isn't being used. Nor is the BinaryFormatter or NDCS, because they both work too (we have unit tests for these things).

I literally just now ran a sample app that uses types like yours, with a Silverlight client and .NET app server. Our unit tests, and the samples for the ebooks, and my current project all work fine when using the standard data portal configuration.

Can you remove your custom proxy/host types and try using the standard data portal? By standard I mean like SimpleNTier, or the Data Portal Configuration ebook samples, or the version of ProjectTracker in svn.

tbaldridge replied on Wednesday, July 13, 2011

I'm a colleague of Steve's and I've posted about this exact issue in the past: http://forums.lhotka.net/forums/p/10405/48778.aspx#48778

The exception is being thrown and caught from within the .Net BinaryFormatter. The basic idea is that the backing fields auto-generated by auto-properties in .NET contain a < character. In other words int Foo {get; set;} gets a  backing store of private int "<intfooFoo>_Foo" or something like that. When the binary formatter goes to serialize this class (as Steve mentioned, it's the CSLA ObservableBindingList<T>) an error is thrown from within the .NET serialzier and caught within those same serializer classes. 

Your unit tests would not catch this issue, because the error never actually bubbles up to the CSLA classes. The only way to see this error is to 1) look at the output window when the class is serialzied or 2) set a XmlException to always stop code execution. 

Granted, our program works fine even with this bug in CSLA, but still it's an exception that is being thrown and it clutters our output window and reduces performance.  

ajj3085 replied on Saturday, July 16, 2011

Does it reduce performance so much that your application is performing badly?  If not, I wouldn't worry about performace implications.  Exceptions might be more expensive than normal code, but they are pretty insignificant.  If you setup VS to break on all exceptions always, there's tons of exceptions thrown within the framework itself that you never normally

As far as the output window goes, what are you using it for?  I closed it five  years ago and haven't found a need for it..  If you're tracing, you shouuld be able to use a TraceFilter to filter it out.

tbaldridge replied on Saturday, July 16, 2011

So you're suggesting we throw out a 3 line fix for an exception simply because "it doesn't affect performance enough"....that's just sad.

tmg4340 replied on Sunday, July 17, 2011

Not exactly...

You've identified the issue - auto-generated properties generate this exception. The framework is catching the exception and dealing with it, ostensibly so that you don't ever have to consider it.  Andy is correct - the framework itself throws and catches a whole host of exceptions which you never see or have to care about.  So I wouldn't classify this as a CSLA bug - it's a bug in .NET itself.

Obviously this exception isn't terribly detrimental, otherwise no one would ever use auto-generated properties.  That's actually what you're saying - in order to keep an exception thrown, caught, and dealt with entirely within the framework from getting to the output window; and to get a performance boost that you're likely never to see (given that the issue only happens when the object is serialized and sent over the wire), CSLA can't use auto-generated properties anywhere.  Nor can you in any object you ever write that will be serialized. Thus it's more than a "3 line fix".

Is that really what you want?

- Scott

ajj3085 replied on Sunday, July 17, 2011

I'm suggesting that Rocky has better things to do then convert an auto-property to a older style one for an exception the framework catches and handles on its own. 

Seriously, you don't have anything better to do than worry about an exception you only notice in the output window? 

RockfordLhotka replied on Monday, July 18, 2011

I am puzzled by two things.

First, why is the BinaryFormatter involved at all? You are using a SL client right? Serialization should be handled by MobileFormatter, and the BF shouldn't be invoked.

Second, even if we assume the BF is invoked for some valid reason, it doesn't use XML - it uses a binary format that wouldn't encounter this XML exception. The only way to get the BF to use XML is to use the deprecated SOAP formatter - and I obviously won't do anything to support a deprecated .NET technology.

StefanCop replied on Monday, October 17, 2011

Rocky

I'm also puzzled, because I use a TCP binding out of the "WCF box" (we use WPF). Why an XML encoding problem? I have been unsure if actually binary encoded is used.

Therefore, I looked at the stack a bit in a debugger, and although im not a WCF expert, I got to the conculsion that some validation is made on XML base,  either before or after the actual encoding (that I guessed from method names on the stack indicating something like "validate").

The encoder property of some WCF class was set to BinaryFormatter, which is what I really wanted to be sure.

I could the "first chance exception" narrowed to the already mentioned auto property in our classes and ObservableBindingList (AllowEdit, AllowNew, AllowRemove). So, I stick with the "old style" properties with an explicit internal field. That reduces the chatty messages in VisualStudio's Output. a lot. 

Stefan

RockfordLhotka replied on Monday, October 17, 2011

WCF will use the NetDataContractSwrializer, that is unavoidable. That will use xml, though it defaults to binaryxml, I suspect it goes through the same process.

What is described here sounds like an issue with the NDCS.

rfcdejong replied on Friday, November 02, 2012

We have the same problem in our output window, over hundreds of XmlExceptions. Mostly because we use Criteria with automatic properties incl. a private set. But the core of the xmlExceptiosn are caused by the AllowEdit, AllowNew and AllowRemove properties.

I notice that this is still active in CSLA 4.5, can this be solved to reduce the many XmlExceptions?

This would be enough

/// <summary>
/// Gets or sets a value indicating whether data binding
/// can automatically edit items in this collection.
/// </summary>
public bool AllowEdit { get { return _allowEdit; } set { _allowEdit = value; } }
private bool _allowEdit;

/// <summary>
/// Gets or sets a value indicating whether data binding
/// can automatically add new items to this collection.
/// </summary>
public bool AllowNew { get { return _allowNew; } set { _allowNew = value; } }
private bool _allowNew;

/// <summary>
/// Gets or sets a value indicating whether data binding
/// can automatically remove items from this collection.
/// </summary>

public bool AllowRemove { get { return _allowRemove; } set { _allowRemove = value; } }
private bool _allowRemove;

 

StefanCop replied on Sunday, November 04, 2012

This is not a problem, but rather annoying.

I turned the debbuger option for XmlException on and tried to get the cause. My understanding was, that WCF (BinaryFormatter in my case, but uses XML/XSD to verify the response) is not clean. One part throws an exception because of special characters in the autoproperty backing fields "<propertyname>", but is caught an encoded correctly.

I agree, it would be nice if CSLA base classes wouldn't use auto properties  to reduce that noise in VisualStudio output.

Sten replied on Wednesday, November 21, 2012

For me this is a problem because I get tens of these and all the exceptions cause a noticeable hit in performance

RockfordLhotka replied on Tuesday, November 27, 2012

This is on the bug list.

JonnyBee replied on Tuesday, November 27, 2012

And it is done and will be included in next release.

http://www.lhotka.net/cslabugs/edit_bug.aspx?id=1123

bill.mybiz replied on Friday, January 11, 2013

I am also getting these exceptions. Any idea when the next release is?

rfcdejong replied on Thursday, February 07, 2013

There is a new beta 4.5.11 in which this is fixed.

http://www.lhotka.net/Article.aspx?id=0736fb9a-1460-42db-8040-765d5801ed8b

Copyright (c) Marimer LLC