// 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
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,
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)
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.");
if (rootQName == null &&
graph.GetType () != type &&
- !known_types.Contains (graph.GetType ()) &&
- KnownTypeCollection.GetPrimitiveTypeName (graph.GetType ()) == QName.Empty)
+ IsUnknownType (graph.GetType ()))
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 instName = rootQName;
/* Different names */
known_types.Add (rootType);
-
+
instName = instName ?? KnownTypeCollection.GetPredefinedTypeName (graph.GetType ());
if (instName == QName.Empty)
/* Not a primitive 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 ();