Bug 2205 - DataContractSerializer fails to deserialize KnownType(string[])
Summary: DataContractSerializer fails to deserialize KnownType(string[])
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: WCF assemblies (show other bugs)
Version: 2.10.x
Hardware: PC Windows
: Normal normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2011-11-27 21:24 UTC by ziye shi
Modified: 2015-10-10 22:57 UTC (History)
7 users (show)

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


Attachments
Test case (3.05 KB, application/zip)
2013-10-21 23:29 UTC, Brendan Zagaeski (Xamarin Team, assistant)
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 2205 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
NEW

Description ziye shi 2011-11-27 21:24:34 UTC
The code below should output "Name1,Name2". 
It works fine on .Net 4.0, but it crashes on mono.
I think this bug make the WCF service with return type "MyObject" crash too.

---------------- Source Code ---------------------

using System;
using System.ServiceModel;
using System.Runtime.Serialization;
using System.IO;

namespace ServiceTest
{
    [KnownType(typeof(string[]))]
    [DataContract]
    public class MyObject
    {
        [DataMember]
        public object NameList;
    }

    class Program
    {
        static void Main(string[] args)
        {
            var obj = new MyObject() { NameList = new[] { "Name1", "Name2" } };
            var ser = new DataContractSerializer(typeof(MyObject));
            var stream = new MemoryStream();
            ser.WriteObject(stream, obj);

            stream.Seek(0, SeekOrigin.Begin);
            var obj2 = (MyObject)ser.ReadObject(stream);
            var names = obj2.NameList as string[];
            Console.WriteLine(string.Join(",", names));
        }
    }
}
Comment 1 Martin Baulig 2012-11-15 10:05:57 UTC
Stack trace:

====
[martin@nathan:misc]$ mono E.exe 

Unhandled Exception:
System.InvalidOperationException: Node type Element is not supported in this operation.  (line 1, column 134)
  at System.Xml.XmlReader.ReadContentString (Boolean isText) [0x00000] in <filename unknown>:0 
  at System.Xml.XmlReader.ReadContentString () [0x00000] in <filename unknown>:0 
  at System.Xml.XmlReader.ReadContentAsString () [0x00000] in <filename unknown>:0 
  at System.Xml.XmlDictionaryReader.ReadContentAsString (Int32 maxStringContentLength) [0x00000] in <filename unknown>:0 
  at System.Xml.XmlDictionaryReader.ReadContentAsString () [0x00000] in <filename unknown>:0 
  at System.Xml.XmlDictionaryReader.ReadElementContentAsString () [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlFormatterDeserializer.DeserializePrimitive (System.Type type, System.Xml.XmlReader reader, System.Xml.XmlQualifiedName qname) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Type type, System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.SerializationMap.DeserializeContent (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer, System.String id, Boolean empty) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.SerializationMap.DeserializeContent (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer, System.String id) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.SerializationMap.DeserializeObject (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlFormatterDeserializer.DeserializeByMap (System.Xml.XmlQualifiedName name, System.Type type, System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Type type, System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Xml.XmlReader reader, System.Type declaredType, System.Runtime.Serialization.KnownTypeCollection knownTypes, IDataContractSurrogate surrogate, System.Runtime.Serialization.DataContractResolver resolver, System.Runtime.Serialization.DataContractResolver defaultResolver, System.String name, System.String ns, Boolean verifyObjectName) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.DataContractSerializer.ReadObject (System.Xml.XmlDictionaryReader reader, Boolean verifyObjectName) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlObjectSerializer.ReadObject (System.Xml.XmlDictionaryReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.DataContractSerializer.ReadObject (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlObjectSerializer.ReadObject (System.IO.Stream stream) [0x00000] in <filename unknown>:0 
  at ServiceTest.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidOperationException: Node type Element is not supported in this operation.  (line 1, column 134)
  at System.Xml.XmlReader.ReadContentString (Boolean isText) [0x00000] in <filename unknown>:0 
  at System.Xml.XmlReader.ReadContentString () [0x00000] in <filename unknown>:0 
  at System.Xml.XmlReader.ReadContentAsString () [0x00000] in <filename unknown>:0 
  at System.Xml.XmlDictionaryReader.ReadContentAsString (Int32 maxStringContentLength) [0x00000] in <filename unknown>:0 
  at System.Xml.XmlDictionaryReader.ReadContentAsString () [0x00000] in <filename unknown>:0 
  at System.Xml.XmlDictionaryReader.ReadElementContentAsString () [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlFormatterDeserializer.DeserializePrimitive (System.Type type, System.Xml.XmlReader reader, System.Xml.XmlQualifiedName qname) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Type type, System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.SerializationMap.DeserializeContent (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer, System.String id, Boolean empty) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.SerializationMap.DeserializeContent (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer, System.String id) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.SerializationMap.DeserializeObject (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlFormatterDeserializer.DeserializeByMap (System.Xml.XmlQualifiedName name, System.Type type, System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Type type, System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Xml.XmlReader reader, System.Type declaredType, System.Runtime.Serialization.KnownTypeCollection knownTypes, IDataContractSurrogate surrogate, System.Runtime.Serialization.DataContractResolver resolver, System.Runtime.Serialization.DataContractResolver defaultResolver, System.String name, System.String ns, Boolean verifyObjectName) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.DataContractSerializer.ReadObject (System.Xml.XmlDictionaryReader reader, Boolean verifyObjectName) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlObjectSerializer.ReadObject (System.Xml.XmlDictionaryReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.DataContractSerializer.ReadObject (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.XmlObjectSerializer.ReadObject (System.IO.Stream stream) [0x00000] in <filename unknown>:0 
  at ServiceTest.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0 
[martin@nathan:misc]$ 
=====
Comment 2 Brendan Zagaeski (Xamarin Team, assistant) 2013-10-21 23:19:48 UTC
The "Node type Element is not supported" error seems to be caused by the way Mono serializes the object. This might ultimately be the same issue reported on bug #11801.

Compare the XML serialization from .NET:
> <MyObject xmlns="http://schemas.datacontract.org/2004/07/ServiceTest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
> 	<NameList i:type="a:ArrayOfstring" xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
> 		<a:string>Name1</a:string>
> 		<a:string>Name2</a:string>
> 	</NameList>
> </MyObject>


Against the XML serialization from Mono:
> <MyObject xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ServiceTest">
> 	<NameList>
> 		<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">Name1</string>
> 		<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">Name2</string>
> 	</NameList>
> </MyObject>


Deserializing the Mono output using .NET [1] produces a similar error message:
"Element Data from namespace http://schemas.datacontract.org/2004/07/ServiceTest cannot have child contents to be deserialized as an object. Please use XmlNode[] to deserialize this pattern of XML."


Deserializing the .NET output in .NET works, but deserializing it in Mono causes another problem. "Type not found; name: string, namespace:" See bug #15572.



[1] 
using System;
using System.Runtime.Serialization;
using System.IO;

namespace ServiceTest
{
	[KnownType(typeof(string[]))]
	[DataContract]
	public class MyObject
	{
		[DataMember]
		public object NameList;
	}

	class Program
	{
		static void Main(string[] args)
		{
			var ser = new DataContractSerializer(typeof(MyObject));
			var stream = File.OpenRead ("Serialized.Mono.xml");
//			var stream = File.OpenRead ("Serialized.DotNet.xml");
			var obj2 = (MyObject)ser.ReadObject(stream);
			var names = obj2.NameList as string[];
			Console.WriteLine(string.Join(",", names));
		}
	}
}
Comment 3 Brendan Zagaeski (Xamarin Team, assistant) 2013-10-21 23:29:39 UTC
Created attachment 5197 [details]
Test case

In case it might be more convenient than the pasted code, here's a small zipped up project.

The project includes the XML output files from both Mono and .NET.

Running the project as-is will deserialize the Mono XML serialization.

Switching the commented lines for "ServiceTest.Serialized.Mono.xml" and "ServiceTest.Serialized.DotNet.xml" will switch to the .NET XML serialization. (This is the test scenario for bug #15572)
Comment 4 Brendan Zagaeski (Xamarin Team, assistant) 2013-11-27 01:36:09 UTC
Switching `OutputXsiType` to return `true` for CollectionTypeMap [1] causes the missing `i:type` attribute to be added as needed.

That said, I suspect there might be a counter-example where CollectionTypeMap should return `false` for OutputXsiType because this was the reason for [2].


> [1] https://github.com/mono/mono/blob/master/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs#L599
> [2] https://github.com/mono/mono/commit/9df6e7165969a829a82479d8faee3346fdfa1ae9