Bug 4794 - DataContractSerializer throws an InvalidOperationException when two different types with the same namespace and data contract name are used to create a serializer
Summary: DataContractSerializer throws an InvalidOperationException when two different...
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: WCF assemblies (show other bugs)
Version: master
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-05-01 09:04 UTC by David Ferguson
Modified: 2012-05-03 02:42 UTC (History)
2 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Test replicating the exception. Passes on Windows with .NET 4.0 (1.23 KB, text/x-csharp)
2012-05-01 09:04 UTC, David Ferguson
Details

Description David Ferguson 2012-05-01 09:04:36 UTC
Created attachment 1785 [details]
Test replicating the exception.  Passes on Windows with .NET 4.0

If an application creates multiple DataContractSerializer objects that are based on types that have the same DataContract attribute properties, the internals of the serializer code will fail to create the serializer, resulting in an InvalidOperationException.  This does not occur in Windows.

Here's the exception and stack trace.

System.InvalidOperationException : There is already a registered type for XML name http://somecompany.com/function/api/2010/05:serverError

  at System.Runtime.Serialization.KnownTypeCollection.RegisterContract (System.Type type) [0x0011e] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:934 
  at System.Runtime.Serialization.KnownTypeCollection.DoTryRegister (System.Type type) [0x00046] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:745 
  at System.Runtime.Serialization.KnownTypeCollection.TryRegister (System.Type type) [0x0000c] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:723 
  at System.Runtime.Serialization.KnownTypeCollection.RegisterContract (System.Type type) [0x0006e] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:922 
  at System.Runtime.Serialization.KnownTypeCollection.DoTryRegister (System.Type type) [0x00046] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:745 
  at System.Runtime.Serialization.KnownTypeCollection.TryRegister (System.Type type) [0x0000c] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:723 
  at System.Runtime.Serialization.KnownTypeCollection.InsertItem (Int32 index, System.Type type) [0x00019] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:466 
  at System.Collections.ObjectModel.Collection`1[System.Type].Add (System.Type item) [0x0000c] in /home/dferguson/Development/mono/mono/mcs/class/corlib/System.Collections.ObjectModel/Collection.cs:79 
  at System.Runtime.Serialization.DataContractSerializer.RegisterTypeAsKnown (System.Type type) [0x00026] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs:238 
  at System.Runtime.Serialization.DataContractSerializer.PopulateTypes (IEnumerable`1 knownTypes) [0x00058] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs:226 
  at System.Runtime.Serialization.DataContractSerializer..ctor (System.Type type, IEnumerable`1 knownTypes) [0x0002f] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs:74 
  at System.Runtime.Serialization.DataContractSerializer..ctor (System.Type type) [0x00000] in /home/dferguson/Development/mono/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs:63 
  at UnitTests.SerializationTests.TestMultipleDataContractSameDataContractNameAndNamespace () [0x00001] in /home/dferguson/Development/mono/TestProject/UnitTests/DataContractSerializerTests.cs:54 
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x000d5] in /home/dferguson/Development/mono/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:229 


Attached is a unit test that will replicate the problem.
Comment 1 David Ferguson 2012-05-03 00:24:30 UTC
This was mainly due to how the serializer was creating and referencing the SerializationMap.  The assumption that only one type per qualified name is not accurate based on the behavior from Microsoft.  This is reproduced when a type has another type in its object graph with the same qualified name.  I've changed the code in my repo, in most places, to look up the serial map by object type in addition to qualified name.  There were a few places where that didn't make sense, so I left the search based just on qualified name there.  That could lead to other issues, but I wasn't sure how to fabricate the few scenarios (when we are unable to locate the map by type alone).

In addition, the KnownTypes property on the serializer was incorrectly populating with data when compared to the MS behavior.  The appearance is that the MS data serializer will only populate the KnownTypes collection if they are specifically passed into the constructor (ignoring any discovered known types and known types based on attributes).  I've updated the code to mimic that behavior.

I'll issue a pull request for this shortly once all the regression tests are run.
Comment 2 David Ferguson 2012-05-03 02:42:45 UTC
Pull request at https://github.com/mono/mono/pull/286

Note You need to log in before you can comment on or make changes to this bug.