Catel 3.6.beta and EntityFramework -> SerializationException

Topics: Issues / bugs, Questions
Aug 30, 2013 at 11:06 AM
Hello

I have updatet from catel 3.6 to an beta version.

Now I get an exception when i call a method wich Property from Entity Framework:

SerializationException was unhandled by user code.
Aug 30, 2013 at 11:40 AM
I would need more than that, a call stack, or anything like that. Best would be a repro.
Sep 2, 2013 at 8:44 AM
Edited Sep 2, 2013 at 9:05 AM
Ok. No i have debugged Catel.Core.

The error is in
class: XmlSerializer
method: private void WriteXmlElement(XElement element, string elementName, MemberValue memberValue, Type modelType)
Line:
                if (memberValue.Value == null)
                {
                    writer.WriteStartElement(elementName);
                    writer.WriteAttributeString(catelNamespacePrefix, "IsNull", null, "true");
                    writer.WriteEndElement();
                }
                else if (memberValue.Type != typeToSerialize)
                {
                    serializer.WriteStartObject(writer, memberValue.Value);
                    writer.WriteAttributeString(catelNamespacePrefix, "type", null, typeToSerialize.FullName);              // -> (here)
                    serializer.WriteObjectContent(writer, memberValue.Value);
                    serializer.WriteEndObject(writer);
                }
                else
                {
                    serializer.WriteObject(writer, memberValue.Value);               //-> (here when I set ProxyCreationEnabled = false of EntityFramework)
                }
Exception: Name cannot begin with the '<' character, hexadecimal value 0x3C.

-> I don't realy understand the exception. I can't find an '<' character in any name.

Edit: Ok found the Name. Its: "<ID>k__BackingField". Any field generated automaticaly from entityframework.
But the exception is not clear.
Sep 2, 2013 at 1:19 PM
Sorry. Thats not relay the exception. I have enabled all exceptions. I try to resolve the problem. In other case i upload an repro.
Sep 2, 2013 at 4:58 PM
Ok, I'll await your reply.
Sep 3, 2013 at 8:32 AM
I think the problem is because in my model of entityframework are a lots of circle references. You have an navigation property from one entity to an other an back. But thats normal.

In the newest catel its not possible to serialize this classes?

The error is: "Object graph for type 'MyEntityType' contains cycles and cannot be serialized if reference tracking is disabled."
Sep 4, 2013 at 7:54 AM
We don't support serializing the same reference twice in the same graph. IF you want this implemented, please create an issue and we will do that.
Sep 4, 2013 at 9:39 AM
Hello again.

Now I have some more Infos. I send an message via the messagemediator. The receiving viewmodel sets a property in the registered method which is decorated with the [model] attribute. This is the reason for the exception. When i remove the attribut no error occurs.

The exeption is thrown at:

class: WeakAction
 public bool Execute(TParameter parameter)
        {
            if (this._action != null)
            {
                if (base.IsTargetAlive)
                {
                    this._action.DynamicInvoke(new object[] { base.Target, parameter });        // <- TargetInvocationException
                    return true;
                }
                WeakAction<TParameter>.Log.Debug("Target for '{0}' is no longer alive, weak event being garbage collected", new object[] { this.MethodName });
                this._action = null;
            }
            return false;
        }
Is it possible to debug the Attribute model? I don't know how.

When I change back to an earlier beta version of catel 3.6 it works.
Sep 4, 2013 at 7:37 PM
Please create an issue with a small repro here:

http://catelproject.atlassian.net/

Then we will debug the action.
Sep 5, 2013 at 7:46 AM
Yes I know. But its very difficult to create an repro with entityframwork to share.
Sep 6, 2013 at 5:17 PM
I have added support for cyclic references. Unfortunately nuget doesn't allow me to push the changes yet, but it should be supported in the latest code base (develop branch).

Can you provide the callstack when you get this exception? Then I can take a look at it.
Sep 6, 2013 at 5:19 PM
And now I see that it is also serializing fields. You probably don't want that.

You might want to take a look at this documentation:

https://catelproject.atlassian.net/wiki/display/CTL/Specifying+what+gets+serialized
Sep 27, 2013 at 1:02 PM
Back to this problem :-)

Here is the callstack:
   ConfiguratorControl.dll!ConfiguratorControl.ViewModels.Pages.ProfilePageViewModel.SetActiveProfile(ConfiguratorControl.Database.Profile profile, bool savetoDb) Line 282 C#
ConfiguratorControl.dll!ConfiguratorControl.ViewModels.Pages.ProfilePageViewModel.Initialize() Line 74 + 0x2d bytes C#
Catel.MVVM.dll!Catel.MVVM.ViewModelBase.InitializeViewModel() + 0x38 bytes  
Catel.MVVM.dll!Catel.Windows.Controls.MVVMProviders.Logic.LogicBase.OnTargetControlLoadedInternal.AnonymousMethod__3() + 0x57 bytes 
Catel.MVVM.dll!Catel.Windows.Threading.DispatcherExtensions.BeginInvoke(System.Windows.Threading.Dispatcher dispatcher, System.Action action, bool onlyBeginInvokeWhenNoAccess) + 0x8e bytes    
Catel.MVVM.dll!Catel.Windows.Threading.DispatcherExtensions.BeginInvokeIfRequired(System.Windows.Threading.Dispatcher dispatcher, System.Action action) + 0x27 bytes    
Catel.MVVM.dll!Catel.Windows.Controls.MVVMProviders.Logic.LogicBase.OnTargetControlLoadedInternal(object sender, System.EventArgs e) + 0x278 bytes  
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x7a bytes    
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0x1a8 bytes  
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) + 0x73 bytes  
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs e) + 0x29 bytes 
PresentationFramework.dll!System.Windows.BroadcastEventHelper.BroadcastEvent(System.Windows.DependencyObject root, System.Windows.RoutedEvent routedEvent) + 0x149 bytes    
PresentationFramework.dll!System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(object root) + 0x9d bytes    
PresentationCore.dll!MS.Internal.LoadedOrUnloadedOperation.DoWork() + 0x16 bytes    
PresentationCore.dll!System.Windows.Media.MediaContext.FireLoadedPendingCallbacks() + 0x3d bytes    
PresentationCore.dll!System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() + 0x31 bytes   
PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandlerCore(object resizedCompositionTarget) + 0x82 bytes   
PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandler(object resizedCompositionTarget) + 0x2c bytes   
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x56 bytes 
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x3a bytes    
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() + 0xac bytes  
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state) + 0x38 bytes 
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0xa7 bytes  
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x16 bytes  
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x41 bytes    
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() + 0x5b bytes  
WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() + 0x16b bytes    
WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x5a bytes 
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x9b bytes    
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) + 0x6b bytes    
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x56 bytes 
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x3a bytes    
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) + 0x10e bytes 
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) + 0xf1 bytes 
[Native to Managed Transition]  
[Managed to Native Transition]  
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) + 0xae bytes  
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) + 0x49 bytes  
WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() + 0x4b bytes  
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) + 0x17 bytes  
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) + 0x6f bytes 
PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) + 0x26 bytes 
PresentationFramework.dll!System.Windows.Application.Run() + 0x1b bytes 
Configurator.exe!Configurator.App.Main() Line 50 + 0xa bytes    C#
[Native to Managed Transition]  
[Managed to Native Transition]  
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x6b bytes    
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x27 bytes  
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x6f bytes   
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0xa7 bytes  
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x16 bytes  
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x41 bytes    
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes   
[Native to Managed Transition]  
Sep 27, 2013 at 6:47 PM
Is the SetActiveProfile method (probably setting a model) easy to extract from the software? Do you only get this exception when you enable "break on all exception" or is this really an exception you cannot get around?
Sep 30, 2013 at 6:51 AM
Hello

In SetActiveProfile I send only an message via MessageMediator. If I debugg the session I end in an otherviewmodel which receives the message.
        private void OnSwitchProfile(ActiveProfileChangedMessage message)
        {
            if (message.Type == ActiveProfileChangedMessage.MessageType.LoadProfile)
            {                
                var manager = ServiceLocator.ResolveType<IMachineInstanceService>();
                Machine = manager.GetMachineInstance();  // Machine is the model which will be set.  If I remove this line no exception. 
            }                                            // If I remove the Attribute [Model] on Machin, also no exception
                                                         // The method GetMachineInstance() don't matter
        }
I always get this exception. "Break on all exception" is disabled.
Oct 6, 2013 at 5:59 PM
That's because setting a property with the [Model] attribute calls IEditableObject.BeginEdit.

Try a simple unit test with this:

var machine = new Machine() as IEditableObject;
machine.BeginEdit();

Does that also throw an exception?
Oct 7, 2013 at 7:23 AM
Edited Oct 7, 2013 at 7:42 AM
Yes, this trows also the same exception.

But why do I get no exception in an older catel version?
Oct 7, 2013 at 7:31 AM
What property values / types?
Oct 7, 2013 at 7:59 AM
I edited my post while you added your answer. Sorry.

I thought its clear, that calling BeginEdit() with an "empty" object throws no exception. :-)

Thats the message of the exception:

Object graph for type 'ConfiguratorControl.Database.HardwareInstance' contains cycles and cannot be serialized if reference tracking is disabled.
Oct 10, 2013 at 6:50 AM
Should I add an issue? My problem ist that I don't realy what's the problem for the exception. And what have changed to the catel version before.
Oct 10, 2013 at 6:55 AM
Well, we have completely rewritten the serialization engine. However we still use the DataContractSerializer under the hood (so that hasn't changed). As the exception says, you have a circular graph. Catel can handle this correctly, but probably EF can't.

The only thing that changed in IEditableObject is that it now uses the XmlSerializer instead of BinarySerializer (to be the same on all platforms).

One easy option is to customize the serializer for your class.
Oct 10, 2013 at 8:42 AM
Edited Oct 10, 2013 at 9:07 AM
I solved the problem.

Decorated the partial class of "ConfiguratorControl.Database.HardwareInstance" with [DataContract(IsReference = true)].
Marked as answer by GeertvanHorrik on 10/25/2013 at 4:51 AM