protected override void InsertItem (int index, Type type)
{
- if (TryRegister (type))
+ if (!Contains (type) && TryRegister (type))
base.InsertItem (index, type);
}
protected override void SetItem (int index, Type type)
{
- if (index == Count)
- InsertItem (index, type);
- else {
+ if (index != Count)
RemoveItem (index);
- if (TryRegister (type))
- base.InsertItem (index - 1, type);
- }
+ if (TryRegister (type))
+ base.InsertItem (index - 1, type);
}
internal SerializationMap FindUserMap (QName qname)
{
- for (int i = 0; i < contracts.Count; i++)
- if (qname == contracts [i].XmlName)
- return contracts [i];
- return null;
+ return contracts.FirstOrDefault (c => c.XmlName == qname);
}
internal Type GetSerializedType (Type type)
return GetContractQName (type, null, null);
}
- static QName GetContractQName (Type type)
+ internal static QName GetContractQName (Type type)
{
var a = GetAttribute<DataContractAttribute> (type);
return a == null ? null : GetContractQName (type, a.Name, a.Namespace);
static QName GetContractQName (Type type, string name, string ns)
{
- if (name == null) {
- // FIXME: there could be decent ways to get
- // the same result...
- name = type.Namespace == null || type.Namespace.Length == 0 ? type.Name : type.FullName.Substring (type.Namespace.Length + 1).Replace ('+', '.');
- if (type.IsGenericType) {
- name = name.Substring (0, name.IndexOf ('`')) + "Of";
- foreach (var t in type.GetGenericArguments ())
- name += t.Name; // FIXME: check namespaces too
- }
- }
+ if (name == null)
+ name = GetDefaultName (type);
if (ns == null)
- ns = DefaultClrNamespaceBase + type.Namespace;
+ ns = GetDefaultNamespace (type);
return new QName (name, ns);
}
}
if (ns == null)
- ns = DefaultClrNamespaceBase + type.Namespace;
+ ns = GetDefaultNamespace (type);
if (name == null)
name = type.Namespace == null ? type.Name : type.FullName.Substring (type.Namespace.Length + 1).Replace ('+', '.');
return new QName (name, ns);
}
+ internal static string GetDefaultName (Type type)
+ {
+ // FIXME: there could be decent ways to get
+ // the same result...
+ string name = type.Namespace == null || type.Namespace.Length == 0 ? type.Name : type.FullName.Substring (type.Namespace.Length + 1).Replace ('+', '.');
+ if (type.IsGenericType) {
+ name = name.Substring (0, name.IndexOf ('`')) + "Of";
+ foreach (var t in type.GetGenericArguments ())
+ name += t.Name; // FIXME: check namespaces too
+ }
+ return name;
+ }
+
+ internal static string GetDefaultNamespace (Type type)
+ {
+ foreach (ContractNamespaceAttribute a in type.Assembly.GetCustomAttributes (typeof (ContractNamespaceAttribute), true))
+ if (a.ClrNamespace == type.Namespace)
+ return a.ContractNamespace;
+ return DefaultClrNamespaceBase + type.Namespace;
+ }
+
static QName GetCollectionQName (Type element)
{
QName eqname = GetStaticQName (element);
static QName GetSerializableQName (Type type)
{
+#if !NET_2_1
+ // First, check XmlSchemaProviderAttribute and try GetSchema() to see if it returns a schema in the expected format.
+ var xpa = type.GetCustomAttribute<XmlSchemaProviderAttribute> (true);
+ if (xpa != null) {
+ var mi = type.GetMethod (xpa.MethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
+ if (mi != null) {
+ try {
+ var xss = new XmlSchemaSet ();
+ return (XmlQualifiedName) mi.Invoke (null, new object [] {xss});
+ } catch {
+ // ignore.
+ }
+ }
+ }
+#endif
+
string xmlName = type.Name;
if (type.IsGenericType) {
xmlName = xmlName.Substring (0, xmlName.IndexOf ('`')) + "Of";
foreach (var t in type.GetGenericArguments ())
xmlName += GetStaticQName (t).Name; // FIXME: check namespaces too
}
- string xmlNamespace = DefaultClrNamespaceBase + type.Namespace;
+ string xmlNamespace = GetDefaultNamespace (type);
var x = GetAttribute<XmlRootAttribute> (type);
if (x != null) {
xmlName = x.ElementName;
if (RegisterEnum (type) != null)
return true;
- if (RegisterContract (type) != null)
+ if (RegisterDictionary (type) != null)
return true;
- if (RegisterIXmlSerializable (type) != null)
+ if (RegisterCollectionContract (type) != null)
return true;
- if (RegisterDictionary (type) != null)
+ if (RegisterContract (type) != null)
return true;
- if (RegisterCollectionContract (type) != null)
+ if (RegisterIXmlSerializable (type) != null)
return true;
if (RegisterCollection (type) != null)
return null;
}
- internal static T GetAttribute<T> (MemberInfo mi) where T : Attribute
+ internal static T GetAttribute<T> (ICustomAttributeProvider ap) where T : Attribute
{
- object [] atts = mi.GetCustomAttributes (typeof (T), false);
+ object [] atts = ap.GetCustomAttributes (typeof (T), false);
return atts.Length == 0 ? null : (T) atts [0];
}
if (FindUserMap (qname) != null)
throw new InvalidOperationException (String.Format ("There is already a registered type for XML name {0}", qname));
- SharedTypeMap ret =
- new SharedTypeMap (type, qname, this);
+ SharedTypeMap ret = new SharedTypeMap (type, qname, this);
contracts.Add (ret);
+ ret.Initialize ();
return ret;
}
contracts.Add (ret);
ret.Initialize ();
+ if (type.BaseType != typeof (object)) {
+ TryRegister (type.BaseType);
+ if (!FindUserMap (type.BaseType).IsContractAllowedType)
+ throw new InvalidDataContractException (String.Format ("To be serializable by data contract, type '{0}' cannot inherit from non-contract and non-Serializable type '{1}'", type, type.BaseType));
+ }
+
object [] attrs = type.GetCustomAttributes (typeof (KnownTypeAttribute), true);
for (int i = 0; i < attrs.Length; i++) {
KnownTypeAttribute kt = (KnownTypeAttribute) attrs [i];
{
DefaultTypeMap ret = new DefaultTypeMap (type, this);
contracts.Add (ret);
+ ret.Initialize ();
return ret;
}