// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
-//
+//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if NET_2_0
+
using System;
using System.Collections;
using System.Collections.Generic;
StreamingContext context;
ReadOnlyCollection<Type> returned_known_types;
KnownTypeCollection known_types;
+ List<Type> specified_known_types;
IDataContractSurrogate surrogate;
DataContractResolver resolver, default_resolver;
QName qname = known_types.GetQName (type);
FillDictionaryString (qname.Name, qname.Namespace);
-
+
}
public DataContractSerializer (Type type, string rootName,
}
#endif
+#if NET_4_5
+ public DataContractSerializer (Type type, DataContractSerializerSettings settings)
+ : this (type, settings.RootName, settings.RootNamespace, settings.KnownTypes,
+ settings.MaxItemsInObjectGraph, settings.IgnoreExtensionDataObject,
+ settings.PreserveObjectReferences, settings.DataContractSurrogate,
+ settings.DataContractResolver)
+ {
+ }
+#endif
+
void PopulateTypes (IEnumerable<Type> knownTypes)
{
if (known_types == null)
- known_types= new KnownTypeCollection ();
+ known_types = new KnownTypeCollection ();
+
+ if (specified_known_types == null)
+ specified_known_types = new List<Type> ();
if (knownTypes != null) {
- foreach (Type t in knownTypes)
+ foreach (Type t in knownTypes) {
known_types.Add (t);
+ specified_known_types.Add (t);
+ }
}
+ RegisterTypeAsKnown (type);
+ }
+
+ void RegisterTypeAsKnown (Type type)
+ {
+ if (known_types.Contains (type))
+ return;
+
Type elementType = type;
- if (type.HasElementType)
+ if (type.HasElementType) {
+ known_types.Add (type);
elementType = type.GetElementType ();
+ }
+
+ known_types.Add (elementType);
/* Get all KnownTypeAttribute-s, including inherited ones */
object [] attrs = elementType.GetCustomAttributes (typeof (KnownTypeAttribute), true);
for (int i = 0; i < attrs.Length; i ++) {
KnownTypeAttribute kt = (KnownTypeAttribute) attrs [i];
- known_types.Add (kt.Type);
+ foreach (var t in kt.GetTypes (elementType))
+ RegisterTypeAsKnown (t);
}
}
public ReadOnlyCollection<Type> KnownTypes {
get {
if (returned_known_types == null)
- returned_known_types = new ReadOnlyCollection<Type> (known_types);
+ returned_known_types = new ReadOnlyCollection<Type> (specified_known_types);
return returned_known_types;
}
}
}
#endif
- private void ReadRootStartElement (XmlReader reader, Type type)
- {
- SerializationMap map =
- known_types.FindUserMap (type);
- QName name = map != null ? map.XmlName :
- KnownTypeCollection.GetPredefinedTypeName (type);
- reader.MoveToContent ();
- reader.ReadStartElement (name.Name, name.Namespace);
- // FIXME: could there be any attributes to handle here?
- reader.Read ();
- }
-
// SP1
public override void WriteObject (XmlWriter writer, object graph)
{
XmlDictionaryWriter writer, object graph)
{
Type rootType = type;
-
+
if (root_name.Value == "")
throw new InvalidDataContractException ("Type '" + type.ToString () +
"' cannot have a DataContract attribute Name set to null or empty string.");
QName rootQName = null;
XmlDictionaryString name, ns;
- if (DataContractResolver != null && DataContractResolver.TryResolveType (graph.GetType (), type, default_resolver, out name, out ns))
+ var graphType = graph.GetType ();
+ if (DataContractResolver != null && DataContractResolver.TryResolveType (graphType, type, default_resolver, out name, out ns))
rootQName = new QName (name.Value, ns.Value);
// It is error unless 1) TypeResolver resolved the type name, 2) the object is the exact type, 3) the object is known or 4) the type is primitive.
- if (rootQName == null &&
- graph.GetType () != type &&
- !known_types.Contains (graph.GetType ()) &&
- KnownTypeCollection.GetPrimitiveTypeName (graph.GetType ()) == QName.Empty)
- throw new SerializationException (String.Format ("Type '{0}' is unexpected. The type should either be registered as a known type, or DataContractResolver should be used.", graph.GetType ()));
+ QName collectionQName;
+ if (KnownTypeCollection.IsInterchangeableCollectionType (type, graphType, out collectionQName)) {
+ graphType = type;
+ rootQName = collectionQName;
+ } else if (graphType != type && rootQName == null && IsUnknownType (type, graphType))
+ throw new SerializationException (String.Format ("Type '{0}' is unexpected. The type should either be registered as a known type, or DataContractResolver should be used.", graphType));
QName instName = rootQName;
rootQName = rootQName ?? known_types.GetQName (rootType);
- QName graph_qname = known_types.GetQName (graph.GetType ());
+ QName graph_qname = known_types.GetQName (graphType);
- known_types.Add (graph.GetType ());
+ known_types.Add (graphType);
if (names_filled)
writer.WriteStartElement (root_name.Value, root_ns.Value);
/* Different names */
known_types.Add (rootType);
-
- instName = instName ?? KnownTypeCollection.GetPredefinedTypeName (graph.GetType ());
+
+ instName = instName ?? KnownTypeCollection.GetPredefinedTypeName (graphType);
if (instName == QName.Empty)
/* Not a primitive type */
instName = graph_qname;
*/
}
+ bool IsUnknownType (Type contractType, Type type)
+ {
+ if (type.IsArray) {
+ if (KnownTypeCollection.GetAttribute<CollectionDataContractAttribute> (contractType) != null ||
+ KnownTypeCollection.GetAttribute<DataContractAttribute> (contractType) != null)
+ return true;
+ }
+ return IsUnknownType (type);
+ }
+
+ bool IsUnknownType (Type type)
+ {
+ if (known_types.Contains (type) ||
+ KnownTypeCollection.GetPrimitiveTypeName (type) != QName.Empty)
+ return false;
+ if (type.IsArray)
+ return IsUnknownType (type.GetElementType ());
+ return true;
+ }
+
public override void WriteEndObject (XmlDictionaryWriter writer)
{
writer.WriteEndElement ();
{
WriteEndObject (XmlDictionaryWriter.CreateDictionaryWriter (writer));
}
+
+#if NET_4_5
+ [MonoTODO]
+ public bool SerializeReadOnlyTypes {
+ get { throw new NotImplementedException (); }
+ }
+#endif
}
}
-#endif