private void IncludeTypes(MemberInfo memberInfo, RecursionLimiter limiter) { foreach (Attribute attr in memberInfo.GetCustomAttributes(typeof(SoapIncludeAttribute), false)) { IncludeType(((SoapIncludeAttribute)attr).Type, limiter); } }
private void IncludeTypes(ICustomAttributeProvider provider, RecursionLimiter limiter) { object[] attrs = provider.GetCustomAttributes(typeof(SoapIncludeAttribute), false); for (int i = 0; i < attrs.Length; i++) { IncludeType(((SoapIncludeAttribute)attrs[i]).Type, limiter); } }
private StructMapping ImportStructLikeMapping(StructModel model, RecursionLimiter limiter) { if (model.TypeDesc.Kind == TypeKind.Root) { return(this.GetRootMapping()); } SoapAttributes a = this.GetAttributes(model.Type); string defaultNs = this.defaultNs; if ((a.SoapType != null) && (a.SoapType.Namespace != null)) { defaultNs = a.SoapType.Namespace; } string typeName = XmlConvert.EncodeLocalName(this.XsdTypeName(model.Type, a, model.TypeDesc.Name)); StructMapping typeMapping = (StructMapping)this.GetTypeMapping(typeName, defaultNs, model.TypeDesc); if (typeMapping == null) { typeMapping = new StructMapping { IsSoap = true, TypeDesc = model.TypeDesc, Namespace = defaultNs, TypeName = typeName }; if (a.SoapType != null) { typeMapping.IncludeInSchema = a.SoapType.IncludeInSchema; } this.typeScope.AddTypeMapping(typeMapping); this.types.Add(typeName, defaultNs, typeMapping); if (limiter.IsExceededLimit) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, typeMapping)); return(typeMapping); } limiter.Depth++; this.InitializeStructMembers(typeMapping, model, limiter); while (limiter.DeferredWorkItems.Count > 0) { int index = limiter.DeferredWorkItems.Count - 1; ImportStructWorkItem item = limiter.DeferredWorkItems[index]; if (this.InitializeStructMembers(item.Mapping, item.Model, limiter)) { limiter.DeferredWorkItems.RemoveAt(index); } } limiter.Depth--; } return(typeMapping); }
private ArrayMapping ImportArrayLikeMapping(ArrayModel model, RecursionLimiter limiter) { ArrayMapping mapping = new ArrayMapping(); mapping.IsSoap = true; TypeMapping itemTypeMapping = ImportTypeMapping(model.Element, limiter); if (itemTypeMapping.TypeDesc.IsValueType && !itemTypeMapping.TypeDesc.IsPrimitive && !itemTypeMapping.TypeDesc.IsEnum) { throw new NotSupportedException(SR.Format(SR.XmlRpcArrayOfValueTypes, model.TypeDesc.FullName)); } mapping.TypeDesc = model.TypeDesc; mapping.Elements = new ElementAccessor[] { CreateElementAccessor(itemTypeMapping, mapping.Namespace) }; SetArrayMappingType(mapping); // in the case of an ArrayMapping we can have more that one mapping correspond to a type // examples of that are ArrayList and object[] both will map tp ArrayOfur-type // so we create a link list for all mappings of the same XSD type ArrayMapping existingMapping = (ArrayMapping)_types[mapping.TypeName, mapping.Namespace]; if (existingMapping != null) { ArrayMapping first = existingMapping; while (existingMapping != null) { if (existingMapping.TypeDesc == model.TypeDesc) { return(existingMapping); } existingMapping = existingMapping.Next; } mapping.Next = first; _types[mapping.TypeName, mapping.Namespace] = mapping; return(mapping); } _typeScope.AddTypeMapping(mapping); _types.Add(mapping.TypeName, mapping.Namespace, mapping); IncludeTypes(model.Type); return(mapping); }
private ArrayMapping ImportArrayLikeMapping(ArrayModel model, RecursionLimiter limiter) { ArrayMapping mapping = new ArrayMapping { IsSoap = true }; TypeMapping mapping2 = this.ImportTypeMapping(model.Element, limiter); if ((mapping2.TypeDesc.IsValueType && !mapping2.TypeDesc.IsPrimitive) && !mapping2.TypeDesc.IsEnum) { throw new NotSupportedException(Res.GetString("XmlRpcArrayOfValueTypes", new object[] { model.TypeDesc.FullName })); } mapping.TypeDesc = model.TypeDesc; mapping.Elements = new ElementAccessor[] { CreateElementAccessor(mapping2, mapping.Namespace) }; this.SetArrayMappingType(mapping); ArrayMapping next = (ArrayMapping)this.types[mapping.TypeName, mapping.Namespace]; if (next != null) { ArrayMapping mapping4 = next; while (next != null) { if (next.TypeDesc == model.TypeDesc) { return(next); } next = next.Next; } mapping.Next = mapping4; this.types[mapping.TypeName, mapping.Namespace] = mapping; return(mapping); } this.typeScope.AddTypeMapping(mapping); this.types.Add(mapping.TypeName, mapping.Namespace, mapping); this.IncludeTypes(model.Type); return(mapping); }
private MemberMapping ImportMemberMapping(XmlReflectionMember xmlReflectionMember, string ns, XmlReflectionMember[] xmlReflectionMembers, XmlSchemaForm form, RecursionLimiter limiter) { SoapAttributes a = xmlReflectionMember.SoapAttributes; if (a.SoapIgnore) return null; MemberMapping member = new MemberMapping(); member.IsSoap = true; member.Name = xmlReflectionMember.MemberName; bool checkSpecified = XmlReflectionImporter.FindSpecifiedMember(xmlReflectionMember.MemberName, xmlReflectionMembers) != null; FieldModel model = new FieldModel(xmlReflectionMember.MemberName, xmlReflectionMember.MemberType, _typeScope.GetTypeDesc(xmlReflectionMember.MemberType), checkSpecified, false); member.CheckShouldPersist = model.CheckShouldPersist; member.CheckSpecified = model.CheckSpecified; member.ReadOnly = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor; ImportAccessorMapping(member, model, a, ns, form, limiter); if (xmlReflectionMember.OverrideIsNullable) member.Elements[0].IsNullable = false; return member; }
private ArrayMapping ImportArrayLikeMapping(ArrayModel model, RecursionLimiter limiter) { ArrayMapping mapping = new ArrayMapping(); mapping.IsSoap = true; TypeMapping itemTypeMapping = ImportTypeMapping(model.Element, limiter); if (itemTypeMapping.TypeDesc.IsValueType && !itemTypeMapping.TypeDesc.IsPrimitive && !itemTypeMapping.TypeDesc.IsEnum) throw new NotSupportedException(SR.Format(SR.XmlRpcArrayOfValueTypes, model.TypeDesc.FullName)); mapping.TypeDesc = model.TypeDesc; mapping.Elements = new ElementAccessor[] { CreateElementAccessor(itemTypeMapping, mapping.Namespace) }; SetArrayMappingType(mapping); // in the case of an ArrayMapping we can have more that one mapping correspond to a type // examples of that are ArrayList and object[] both will map tp ArrayOfur-type // so we create a link list for all mappings of the same XSD type ArrayMapping existingMapping = (ArrayMapping)_types[mapping.TypeName, mapping.Namespace]; if (existingMapping != null) { ArrayMapping first = existingMapping; while (existingMapping != null) { if (existingMapping.TypeDesc == model.TypeDesc) return existingMapping; existingMapping = existingMapping.Next; } mapping.Next = first; _types[mapping.TypeName, mapping.Namespace] = mapping; return mapping; } _typeScope.AddTypeMapping(mapping); _types.Add(mapping.TypeName, mapping.Namespace, mapping); IncludeTypes(model.Type.GetTypeInfo()); return mapping; }
private StructMapping ImportStructLikeMapping(StructModel model, RecursionLimiter limiter) { if (model.TypeDesc.Kind == TypeKind.Root) return GetRootMapping(); SoapAttributes a = GetAttributes(model.Type); string typeNs = _defaultNs; if (a.SoapType != null && a.SoapType.Namespace != null) typeNs = a.SoapType.Namespace; string typeName = XsdTypeName(model.Type, a, model.TypeDesc.Name); typeName = XmlConvert.EncodeLocalName(typeName); StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc); if (mapping == null) { mapping = new StructMapping(); mapping.IsSoap = true; mapping.TypeDesc = model.TypeDesc; mapping.Namespace = typeNs; mapping.TypeName = typeName; if (a.SoapType != null) mapping.IncludeInSchema = a.SoapType.IncludeInSchema; _typeScope.AddTypeMapping(mapping); _types.Add(typeName, typeNs, mapping); if (limiter.IsExceededLimit) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping)); return mapping; } limiter.Depth++; InitializeStructMembers(mapping, model, limiter); while (limiter.DeferredWorkItems.Count > 0) { int index = limiter.DeferredWorkItems.Count - 1; ImportStructWorkItem item = limiter.DeferredWorkItems[index]; if (InitializeStructMembers(item.Mapping, item.Model, limiter)) { // // if InitializeStructMembers returns true, then there were *no* chages to the DeferredWorkItems // #if DEBUG // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe if (index != limiter.DeferredWorkItems.Count - 1) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "DeferredWorkItems.Count have changed")); if (item != limiter.DeferredWorkItems[index]) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "DeferredWorkItems.Top have changed")); #endif // Remove the last work item limiter.DeferredWorkItems.RemoveAt(index); } } limiter.Depth--; } return mapping; }
private TypeMapping ImportTypeMapping(TypeModel model, RecursionLimiter limiter) { return ImportTypeMapping(model, String.Empty, limiter); }
private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, SoapAttributes a, string ns, XmlSchemaForm form, RecursionLimiter limiter) { Type accessorType = model.FieldType; string accessorName = model.Name; accessor.TypeDesc = _typeScope.GetTypeDesc(accessorType); if (accessor.TypeDesc.IsVoid) { throw new InvalidOperationException(SR.XmlInvalidVoid); } SoapAttributeFlags flags = a.GetSoapFlags(); if ((flags & SoapAttributeFlags.Attribute) == SoapAttributeFlags.Attribute) { if (!accessor.TypeDesc.IsPrimitive && !accessor.TypeDesc.IsEnum) { throw new InvalidOperationException(SR.Format(SR.XmlIllegalSoapAttribute, accessorName, accessor.TypeDesc.FullName)); } if ((flags & SoapAttributeFlags.Attribute) != flags) { throw new InvalidOperationException(SR.XmlInvalidElementAttribute); } AttributeAccessor attribute = new AttributeAccessor(); attribute.Name = Accessor.EscapeQName(a.SoapAttribute == null || a.SoapAttribute.AttributeName.Length == 0 ? accessorName : a.SoapAttribute.AttributeName); attribute.Namespace = a.SoapAttribute == null || a.SoapAttribute.Namespace == null ? ns : a.SoapAttribute.Namespace; attribute.Form = XmlSchemaForm.Qualified; // attributes are always qualified since they're only used for encoded soap headers attribute.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(accessorType), (a.SoapAttribute == null ? String.Empty : a.SoapAttribute.DataType), limiter); attribute.Default = GetDefaultValue(model.FieldTypeDesc, a); accessor.Attribute = attribute; accessor.Elements = Array.Empty <ElementAccessor>(); } else { if ((flags & SoapAttributeFlags.Element) != flags) { throw new InvalidOperationException(SR.XmlInvalidElementAttribute); } ElementAccessor element = new ElementAccessor(); element.IsSoap = true; element.Name = XmlConvert.EncodeLocalName(a.SoapElement == null || a.SoapElement.ElementName.Length == 0 ? accessorName : a.SoapElement.ElementName); element.Namespace = ns; element.Form = form; element.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(accessorType), (a.SoapElement == null ? String.Empty : a.SoapElement.DataType), limiter); if (a.SoapElement != null) { element.IsNullable = a.SoapElement.IsNullable; } accessor.Elements = new ElementAccessor[] { element }; } }
private TypeMapping ImportTypeMapping(TypeModel model, RecursionLimiter limiter) { return(ImportTypeMapping(model, String.Empty, limiter)); }
private void IncludeTypes(MemberInfo memberInfo, RecursionLimiter limiter) { object[] attrs = memberInfo.GetCustomAttributes(typeof(XmlIncludeAttribute), false).ToArray(); for (int i = 0; i < attrs.Length; i++) { Type type = ((XmlIncludeAttribute)attrs[i]).Type; IncludeType(type, limiter); } }
private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, string ns, Type choiceIdentifierType, bool rpc, bool openModel, RecursionLimiter limiter) { XmlSchemaForm qualified = XmlSchemaForm.Qualified; int arrayNestingLevel = this.arrayNestingLevel; int order = -1; XmlArrayItemAttributes savedArrayItemAttributes = this.savedArrayItemAttributes; string savedArrayNamespace = this.savedArrayNamespace; this.arrayNestingLevel = 0; this.savedArrayItemAttributes = null; this.savedArrayNamespace = null; Type fieldType = model.FieldType; string name = model.Name; ArrayList list = new ArrayList(); System.Xml.Serialization.NameTable scope = new System.Xml.Serialization.NameTable(); accessor.TypeDesc = this.typeScope.GetTypeDesc(fieldType); XmlAttributeFlags xmlFlags = a.XmlFlags; accessor.Ignore = a.XmlIgnore; if (rpc) { this.CheckTopLevelAttributes(a, name); } else { this.CheckAmbiguousChoice(a, fieldType, name); } XmlAttributeFlags flags2 = XmlAttributeFlags.ChoiceIdentifier | XmlAttributeFlags.AnyElements | XmlAttributeFlags.Elements | XmlAttributeFlags.Text; XmlAttributeFlags flags3 = XmlAttributeFlags.AnyAttribute | XmlAttributeFlags.Attribute; XmlAttributeFlags flags4 = XmlAttributeFlags.ArrayItems | XmlAttributeFlags.Array; if (((xmlFlags & flags4) != ((XmlAttributeFlags) 0)) && (fieldType == typeof(byte[]))) { accessor.TypeDesc = this.typeScope.GetArrayTypeDesc(fieldType); } if (a.XmlChoiceIdentifier != null) { accessor.ChoiceIdentifier = new ChoiceIdentifierAccessor(); accessor.ChoiceIdentifier.MemberName = a.XmlChoiceIdentifier.MemberName; accessor.ChoiceIdentifier.Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(choiceIdentifierType), ns, ImportContext.Element, string.Empty, null, limiter); this.CheckChoiceIdentifierMapping((EnumMapping) accessor.ChoiceIdentifier.Mapping); } if (accessor.TypeDesc.IsArrayLike) { Type arrayElementType = TypeScope.GetArrayElementType(fieldType, model.FieldTypeDesc.FullName + "." + model.Name); if ((xmlFlags & flags3) != ((XmlAttributeFlags) 0)) { if ((xmlFlags & flags3) != xmlFlags) { throw new InvalidOperationException(Res.GetString("XmlIllegalAttributesArrayAttribute")); } if (((a.XmlAttribute != null) && !accessor.TypeDesc.ArrayElementTypeDesc.IsPrimitive) && !accessor.TypeDesc.ArrayElementTypeDesc.IsEnum) { if (accessor.TypeDesc.ArrayElementTypeDesc.Kind == TypeKind.Serializable) { throw new InvalidOperationException(Res.GetString("XmlIllegalAttrOrTextInterface", new object[] { name, accessor.TypeDesc.ArrayElementTypeDesc.FullName, typeof(IXmlSerializable).Name })); } throw new InvalidOperationException(Res.GetString("XmlIllegalAttrOrText", new object[] { name, accessor.TypeDesc.ArrayElementTypeDesc.FullName })); } bool repeats = (a.XmlAttribute != null) && (accessor.TypeDesc.ArrayElementTypeDesc.IsPrimitive || accessor.TypeDesc.ArrayElementTypeDesc.IsEnum); if (a.XmlAnyAttribute != null) { a.XmlAttribute = new XmlAttributeAttribute(); } AttributeAccessor accessor2 = new AttributeAccessor(); Type type = (a.XmlAttribute.Type == null) ? arrayElementType : a.XmlAttribute.Type; this.typeScope.GetTypeDesc(type); accessor2.Name = Accessor.EscapeQName((a.XmlAttribute.AttributeName.Length == 0) ? name : a.XmlAttribute.AttributeName); accessor2.Namespace = (a.XmlAttribute.Namespace == null) ? ns : a.XmlAttribute.Namespace; accessor2.Form = a.XmlAttribute.Form; if ((accessor2.Form == XmlSchemaForm.None) && (ns != accessor2.Namespace)) { accessor2.Form = XmlSchemaForm.Qualified; } accessor2.CheckSpecial(); CheckForm(accessor2.Form, ns != accessor2.Namespace); accessor2.Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(type), ns, ImportContext.Attribute, a.XmlAttribute.DataType, null, repeats, false, limiter); accessor2.IsList = repeats; accessor2.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); accessor2.Any = a.XmlAnyAttribute != null; if ((accessor2.Form == XmlSchemaForm.Qualified) && (accessor2.Namespace != ns)) { if (this.xsdAttributes == null) { this.xsdAttributes = new System.Xml.Serialization.NameTable(); } accessor2 = (AttributeAccessor) this.ReconcileAccessor(accessor2, this.xsdAttributes); } accessor.Attribute = accessor2; } else if ((xmlFlags & flags2) != ((XmlAttributeFlags) 0)) { if ((xmlFlags & flags2) != xmlFlags) { throw new InvalidOperationException(Res.GetString("XmlIllegalElementsArrayAttribute")); } if (a.XmlText != null) { TextAccessor accessor3 = new TextAccessor(); Type type4 = (a.XmlText.Type == null) ? arrayElementType : a.XmlText.Type; TypeDesc typeDesc = this.typeScope.GetTypeDesc(type4); accessor3.Name = name; accessor3.Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(type4), ns, ImportContext.Text, a.XmlText.DataType, null, true, false, limiter); if (!(accessor3.Mapping is SpecialMapping) && (typeDesc != this.typeScope.GetTypeDesc(typeof(string)))) { throw new InvalidOperationException(Res.GetString("XmlIllegalArrayTextAttribute", new object[] { name })); } accessor.Text = accessor3; } if (((a.XmlText == null) && (a.XmlElements.Count == 0)) && (a.XmlAnyElements.Count == 0)) { a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc)); } for (int i = 0; i < a.XmlElements.Count; i++) { ElementAccessor accessor4; XmlElementAttribute attribute = a.XmlElements[i]; Type type5 = (attribute.Type == null) ? arrayElementType : attribute.Type; TypeDesc desc2 = this.typeScope.GetTypeDesc(type5); TypeModel typeModel = this.modelScope.GetTypeModel(type5); accessor4 = new ElementAccessor { Namespace = rpc ? null : ((attribute.Namespace == null) ? ns : attribute.Namespace), Mapping = this.ImportTypeMapping(typeModel, rpc ? ns : accessor4.Namespace, ImportContext.Element, attribute.DataType, null, limiter) }; if (a.XmlElements.Count == 1) { accessor4.Name = XmlConvert.EncodeLocalName((attribute.ElementName.Length == 0) ? name : attribute.ElementName); } else { accessor4.Name = (attribute.ElementName.Length == 0) ? accessor4.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(attribute.ElementName); } accessor4.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); if ((attribute.IsNullableSpecified && !attribute.IsNullable) && typeModel.TypeDesc.IsOptionalValue) { throw new InvalidOperationException(Res.GetString("XmlInvalidNotNullable", new object[] { typeModel.TypeDesc.BaseTypeDesc.FullName, "XmlElement" })); } accessor4.IsNullable = attribute.IsNullableSpecified ? attribute.IsNullable : typeModel.TypeDesc.IsOptionalValue; accessor4.Form = rpc ? XmlSchemaForm.Unqualified : ((attribute.Form == XmlSchemaForm.None) ? qualified : attribute.Form); CheckNullable(accessor4.IsNullable, desc2, accessor4.Mapping); if (!rpc) { CheckForm(accessor4.Form, ns != accessor4.Namespace); accessor4 = this.ReconcileLocalAccessor(accessor4, ns); } if (attribute.Order != -1) { if ((attribute.Order != order) && (order != -1)) { throw new InvalidOperationException(Res.GetString("XmlSequenceMatch", new object[] { "Order" })); } order = attribute.Order; } AddUniqueAccessor(scope, accessor4); list.Add(accessor4); } System.Xml.Serialization.NameTable table2 = new System.Xml.Serialization.NameTable(); for (int j = 0; j < a.XmlAnyElements.Count; j++) { XmlAnyElementAttribute attribute2 = a.XmlAnyElements[j]; Type c = typeof(IXmlSerializable).IsAssignableFrom(arrayElementType) ? arrayElementType : (typeof(XmlNode).IsAssignableFrom(arrayElementType) ? arrayElementType : typeof(XmlElement)); if (!arrayElementType.IsAssignableFrom(c)) { throw new InvalidOperationException(Res.GetString("XmlIllegalAnyElement", new object[] { arrayElementType.FullName })); } string str3 = (attribute2.Name.Length == 0) ? attribute2.Name : XmlConvert.EncodeLocalName(attribute2.Name); string str4 = attribute2.NamespaceSpecified ? attribute2.Namespace : null; if (table2[str3, str4] == null) { table2[str3, str4] = attribute2; if (scope[str3, (str4 == null) ? ns : str4] != null) { throw new InvalidOperationException(Res.GetString("XmlAnyElementDuplicate", new object[] { name, attribute2.Name, (attribute2.Namespace == null) ? "null" : attribute2.Namespace })); } ElementAccessor accessor5 = new ElementAccessor { Name = str3, Namespace = (str4 == null) ? ns : str4, Any = true, AnyNamespaces = str4 }; TypeDesc desc3 = this.typeScope.GetTypeDesc(c); TypeModel model3 = this.modelScope.GetTypeModel(c); if (accessor5.Name.Length > 0) { model3.TypeDesc.IsMixed = true; } accessor5.Mapping = this.ImportTypeMapping(model3, accessor5.Namespace, ImportContext.Element, string.Empty, null, limiter); accessor5.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); accessor5.IsNullable = false; accessor5.Form = qualified; CheckNullable(accessor5.IsNullable, desc3, accessor5.Mapping); if (!rpc) { CheckForm(accessor5.Form, ns != accessor5.Namespace); accessor5 = this.ReconcileLocalAccessor(accessor5, ns); } scope.Add(accessor5.Name, accessor5.Namespace, accessor5); list.Add(accessor5); if (attribute2.Order != -1) { if ((attribute2.Order != order) && (order != -1)) { throw new InvalidOperationException(Res.GetString("XmlSequenceMatch", new object[] { "Order" })); } order = attribute2.Order; } } } } else { if (((xmlFlags & flags4) != ((XmlAttributeFlags) 0)) && ((xmlFlags & flags4) != xmlFlags)) { throw new InvalidOperationException(Res.GetString("XmlIllegalArrayArrayAttribute")); } TypeDesc desc4 = this.typeScope.GetTypeDesc(arrayElementType); if (a.XmlArray == null) { a.XmlArray = CreateArrayAttribute(accessor.TypeDesc); } if (CountAtLevel(a.XmlArrayItems, this.arrayNestingLevel) == 0) { a.XmlArrayItems.Add(CreateArrayItemAttribute(desc4, this.arrayNestingLevel)); } ElementAccessor accessor6 = new ElementAccessor { Name = XmlConvert.EncodeLocalName((a.XmlArray.ElementName.Length == 0) ? name : a.XmlArray.ElementName), Namespace = rpc ? null : ((a.XmlArray.Namespace == null) ? ns : a.XmlArray.Namespace) }; this.savedArrayItemAttributes = a.XmlArrayItems; this.savedArrayNamespace = accessor6.Namespace; ArrayMapping mapping = this.ImportArrayLikeMapping(this.modelScope.GetArrayModel(fieldType), ns, limiter); accessor6.Mapping = mapping; accessor6.IsNullable = a.XmlArray.IsNullable; accessor6.Form = rpc ? XmlSchemaForm.Unqualified : ((a.XmlArray.Form == XmlSchemaForm.None) ? qualified : a.XmlArray.Form); order = a.XmlArray.Order; CheckNullable(accessor6.IsNullable, accessor.TypeDesc, accessor6.Mapping); if (!rpc) { CheckForm(accessor6.Form, ns != accessor6.Namespace); accessor6 = this.ReconcileLocalAccessor(accessor6, ns); } this.savedArrayItemAttributes = null; this.savedArrayNamespace = null; AddUniqueAccessor(scope, accessor6); list.Add(accessor6); } } else if (!accessor.TypeDesc.IsVoid) { XmlAttributeFlags flags5 = XmlAttributeFlags.XmlnsDeclarations | XmlAttributeFlags.ChoiceIdentifier | XmlAttributeFlags.AnyElements | XmlAttributeFlags.Attribute | XmlAttributeFlags.Elements | XmlAttributeFlags.Text; if ((xmlFlags & flags5) != xmlFlags) { throw new InvalidOperationException(Res.GetString("XmlIllegalAttribute")); } if (accessor.TypeDesc.IsPrimitive || accessor.TypeDesc.IsEnum) { if (a.XmlAnyElements.Count > 0) { throw new InvalidOperationException(Res.GetString("XmlIllegalAnyElement", new object[] { accessor.TypeDesc.FullName })); } if (a.XmlAttribute != null) { if (a.XmlElements.Count > 0) { throw new InvalidOperationException(Res.GetString("XmlIllegalAttribute")); } if (a.XmlAttribute.Type != null) { throw new InvalidOperationException(Res.GetString("XmlIllegalType", new object[] { "XmlAttribute" })); } AttributeAccessor accessor7 = new AttributeAccessor { Name = Accessor.EscapeQName((a.XmlAttribute.AttributeName.Length == 0) ? name : a.XmlAttribute.AttributeName), Namespace = (a.XmlAttribute.Namespace == null) ? ns : a.XmlAttribute.Namespace, Form = a.XmlAttribute.Form }; if ((accessor7.Form == XmlSchemaForm.None) && (ns != accessor7.Namespace)) { accessor7.Form = XmlSchemaForm.Qualified; } accessor7.CheckSpecial(); CheckForm(accessor7.Form, ns != accessor7.Namespace); accessor7.Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(fieldType), ns, ImportContext.Attribute, a.XmlAttribute.DataType, null, limiter); accessor7.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); accessor7.Any = a.XmlAnyAttribute != null; if ((accessor7.Form == XmlSchemaForm.Qualified) && (accessor7.Namespace != ns)) { if (this.xsdAttributes == null) { this.xsdAttributes = new System.Xml.Serialization.NameTable(); } accessor7 = (AttributeAccessor) this.ReconcileAccessor(accessor7, this.xsdAttributes); } accessor.Attribute = accessor7; } else { if (a.XmlText != null) { if ((a.XmlText.Type != null) && (a.XmlText.Type != fieldType)) { throw new InvalidOperationException(Res.GetString("XmlIllegalType", new object[] { "XmlText" })); } TextAccessor accessor8 = new TextAccessor { Name = name, Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(fieldType), ns, ImportContext.Text, a.XmlText.DataType, null, limiter) }; accessor.Text = accessor8; } else if (a.XmlElements.Count == 0) { a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc)); } for (int k = 0; k < a.XmlElements.Count; k++) { XmlElementAttribute attribute3 = a.XmlElements[k]; if ((attribute3.Type != null) && (this.typeScope.GetTypeDesc(attribute3.Type) != accessor.TypeDesc)) { throw new InvalidOperationException(Res.GetString("XmlIllegalType", new object[] { "XmlElement" })); } ElementAccessor accessor9 = new ElementAccessor { Name = XmlConvert.EncodeLocalName((attribute3.ElementName.Length == 0) ? name : attribute3.ElementName), Namespace = rpc ? null : ((attribute3.Namespace == null) ? ns : attribute3.Namespace) }; TypeModel model4 = this.modelScope.GetTypeModel(fieldType); accessor9.Mapping = this.ImportTypeMapping(model4, rpc ? ns : accessor9.Namespace, ImportContext.Element, attribute3.DataType, null, limiter); if (accessor9.Mapping.TypeDesc.Kind == TypeKind.Node) { accessor9.Any = true; } accessor9.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); if ((attribute3.IsNullableSpecified && !attribute3.IsNullable) && model4.TypeDesc.IsOptionalValue) { throw new InvalidOperationException(Res.GetString("XmlInvalidNotNullable", new object[] { model4.TypeDesc.BaseTypeDesc.FullName, "XmlElement" })); } accessor9.IsNullable = attribute3.IsNullableSpecified ? attribute3.IsNullable : model4.TypeDesc.IsOptionalValue; accessor9.Form = rpc ? XmlSchemaForm.Unqualified : ((attribute3.Form == XmlSchemaForm.None) ? qualified : attribute3.Form); CheckNullable(accessor9.IsNullable, accessor.TypeDesc, accessor9.Mapping); if (!rpc) { CheckForm(accessor9.Form, ns != accessor9.Namespace); accessor9 = this.ReconcileLocalAccessor(accessor9, ns); } if (attribute3.Order != -1) { if ((attribute3.Order != order) && (order != -1)) { throw new InvalidOperationException(Res.GetString("XmlSequenceMatch", new object[] { "Order" })); } order = attribute3.Order; } AddUniqueAccessor(scope, accessor9); list.Add(accessor9); } } } else if (a.Xmlns) { if (xmlFlags != XmlAttributeFlags.XmlnsDeclarations) { throw new InvalidOperationException(Res.GetString("XmlSoleXmlnsAttribute")); } if (fieldType != typeof(XmlSerializerNamespaces)) { throw new InvalidOperationException(Res.GetString("XmlXmlnsInvalidType", new object[] { name, fieldType.FullName, typeof(XmlSerializerNamespaces).FullName })); } accessor.Xmlns = new XmlnsAccessor(); accessor.Ignore = true; } else { if ((a.XmlAttribute != null) || (a.XmlText != null)) { if (accessor.TypeDesc.Kind == TypeKind.Serializable) { throw new InvalidOperationException(Res.GetString("XmlIllegalAttrOrTextInterface", new object[] { name, accessor.TypeDesc.FullName, typeof(IXmlSerializable).Name })); } throw new InvalidOperationException(Res.GetString("XmlIllegalAttrOrText", new object[] { name, accessor.TypeDesc })); } if ((a.XmlElements.Count == 0) && (a.XmlAnyElements.Count == 0)) { a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc)); } for (int m = 0; m < a.XmlElements.Count; m++) { XmlElementAttribute attribute4 = a.XmlElements[m]; Type type7 = (attribute4.Type == null) ? fieldType : attribute4.Type; TypeDesc desc5 = this.typeScope.GetTypeDesc(type7); ElementAccessor accessor10 = new ElementAccessor(); TypeModel model5 = this.modelScope.GetTypeModel(type7); accessor10.Namespace = rpc ? null : ((attribute4.Namespace == null) ? ns : attribute4.Namespace); accessor10.Mapping = this.ImportTypeMapping(model5, rpc ? ns : accessor10.Namespace, ImportContext.Element, attribute4.DataType, null, false, openModel, limiter); if (a.XmlElements.Count == 1) { accessor10.Name = XmlConvert.EncodeLocalName((attribute4.ElementName.Length == 0) ? name : attribute4.ElementName); } else { accessor10.Name = (attribute4.ElementName.Length == 0) ? accessor10.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(attribute4.ElementName); } accessor10.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); if ((attribute4.IsNullableSpecified && !attribute4.IsNullable) && model5.TypeDesc.IsOptionalValue) { throw new InvalidOperationException(Res.GetString("XmlInvalidNotNullable", new object[] { model5.TypeDesc.BaseTypeDesc.FullName, "XmlElement" })); } accessor10.IsNullable = attribute4.IsNullableSpecified ? attribute4.IsNullable : model5.TypeDesc.IsOptionalValue; accessor10.Form = rpc ? XmlSchemaForm.Unqualified : ((attribute4.Form == XmlSchemaForm.None) ? qualified : attribute4.Form); CheckNullable(accessor10.IsNullable, desc5, accessor10.Mapping); if (!rpc) { CheckForm(accessor10.Form, ns != accessor10.Namespace); accessor10 = this.ReconcileLocalAccessor(accessor10, ns); } if (attribute4.Order != -1) { if ((attribute4.Order != order) && (order != -1)) { throw new InvalidOperationException(Res.GetString("XmlSequenceMatch", new object[] { "Order" })); } order = attribute4.Order; } AddUniqueAccessor(scope, accessor10); list.Add(accessor10); } System.Xml.Serialization.NameTable table3 = new System.Xml.Serialization.NameTable(); for (int n = 0; n < a.XmlAnyElements.Count; n++) { XmlAnyElementAttribute attribute5 = a.XmlAnyElements[n]; Type type8 = typeof(IXmlSerializable).IsAssignableFrom(fieldType) ? fieldType : (typeof(XmlNode).IsAssignableFrom(fieldType) ? fieldType : typeof(XmlElement)); if (!fieldType.IsAssignableFrom(type8)) { throw new InvalidOperationException(Res.GetString("XmlIllegalAnyElement", new object[] { fieldType.FullName })); } string str5 = (attribute5.Name.Length == 0) ? attribute5.Name : XmlConvert.EncodeLocalName(attribute5.Name); string str6 = attribute5.NamespaceSpecified ? attribute5.Namespace : null; if (table3[str5, str6] == null) { table3[str5, str6] = attribute5; if (scope[str5, (str6 == null) ? ns : str6] != null) { throw new InvalidOperationException(Res.GetString("XmlAnyElementDuplicate", new object[] { name, attribute5.Name, (attribute5.Namespace == null) ? "null" : attribute5.Namespace })); } ElementAccessor accessor11 = new ElementAccessor { Name = str5, Namespace = (str6 == null) ? ns : str6, Any = true, AnyNamespaces = str6 }; TypeDesc desc6 = this.typeScope.GetTypeDesc(type8); TypeModel model6 = this.modelScope.GetTypeModel(type8); if (accessor11.Name.Length > 0) { model6.TypeDesc.IsMixed = true; } accessor11.Mapping = this.ImportTypeMapping(model6, accessor11.Namespace, ImportContext.Element, string.Empty, null, false, openModel, limiter); accessor11.Default = this.GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); accessor11.IsNullable = false; accessor11.Form = qualified; CheckNullable(accessor11.IsNullable, desc6, accessor11.Mapping); if (!rpc) { CheckForm(accessor11.Form, ns != accessor11.Namespace); accessor11 = this.ReconcileLocalAccessor(accessor11, ns); } if (attribute5.Order != -1) { if ((attribute5.Order != order) && (order != -1)) { throw new InvalidOperationException(Res.GetString("XmlSequenceMatch", new object[] { "Order" })); } order = attribute5.Order; } scope.Add(accessor11.Name, accessor11.Namespace, accessor11); list.Add(accessor11); } } } } accessor.Elements = (ElementAccessor[]) list.ToArray(typeof(ElementAccessor)); accessor.SequenceId = order; if (rpc) { if ((accessor.TypeDesc.IsArrayLike && (accessor.Elements.Length > 0)) && !(accessor.Elements[0].Mapping is ArrayMapping)) { throw new InvalidOperationException(Res.GetString("XmlRpcLitArrayElement", new object[] { accessor.Elements[0].Name })); } if (accessor.Xmlns != null) { throw new InvalidOperationException(Res.GetString("XmlRpcLitXmlns", new object[] { accessor.Name })); } } if (accessor.ChoiceIdentifier != null) { accessor.ChoiceIdentifier.MemberIds = new string[accessor.Elements.Length]; for (int num8 = 0; num8 < accessor.Elements.Length; num8++) { bool flag2 = false; ElementAccessor accessor12 = accessor.Elements[num8]; EnumMapping mapping2 = (EnumMapping) accessor.ChoiceIdentifier.Mapping; for (int num9 = 0; num9 < mapping2.Constants.Length; num9++) { string xmlName = mapping2.Constants[num9].XmlName; if (accessor12.Any && (accessor12.Name.Length == 0)) { string str8 = (accessor12.AnyNamespaces == null) ? "##any" : accessor12.AnyNamespaces; if (!(xmlName.Substring(0, xmlName.Length - 1) == str8)) { continue; } accessor.ChoiceIdentifier.MemberIds[num8] = mapping2.Constants[num9].Name; flag2 = true; break; } int length = xmlName.LastIndexOf(':'); string str9 = (length < 0) ? mapping2.Namespace : xmlName.Substring(0, length); string str10 = (length < 0) ? xmlName : xmlName.Substring(length + 1); if ((accessor12.Name == str10) && (((accessor12.Form == XmlSchemaForm.Unqualified) && string.IsNullOrEmpty(str9)) || (accessor12.Namespace == str9))) { accessor.ChoiceIdentifier.MemberIds[num8] = mapping2.Constants[num9].Name; flag2 = true; break; } } if (!flag2) { if (accessor12.Any && (accessor12.Name.Length == 0)) { throw new InvalidOperationException(Res.GetString("XmlChoiceMissingAnyValue", new object[] { accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName })); } string str11 = ((accessor12.Namespace != null) && (accessor12.Namespace.Length > 0)) ? (accessor12.Namespace + ":" + accessor12.Name) : accessor12.Name; throw new InvalidOperationException(Res.GetString("XmlChoiceMissingValue", new object[] { accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName, str11, accessor12.Name, accessor12.Namespace })); } } } this.arrayNestingLevel = arrayNestingLevel; this.savedArrayItemAttributes = savedArrayItemAttributes; this.savedArrayNamespace = savedArrayNamespace; }
private void CreateArrayElementsFromAttributes(ArrayMapping arrayMapping, XmlArrayItemAttributes attributes, Type arrayElementType, string arrayElementNs, RecursionLimiter limiter) { System.Xml.Serialization.NameTable scope = new System.Xml.Serialization.NameTable(); for (int i = 0; (attributes != null) && (i < attributes.Count); i++) { XmlArrayItemAttribute attribute = attributes[i]; if (attribute.NestingLevel == this.arrayNestingLevel) { ElementAccessor accessor; Type type = (attribute.Type != null) ? attribute.Type : arrayElementType; TypeDesc typeDesc = this.typeScope.GetTypeDesc(type); accessor = new ElementAccessor { Namespace = (attribute.Namespace == null) ? arrayElementNs : attribute.Namespace, Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(type), accessor.Namespace, ImportContext.Element, attribute.DataType, null, limiter), Name = (attribute.ElementName.Length == 0) ? accessor.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(attribute.ElementName), IsNullable = attribute.IsNullableSpecified ? attribute.IsNullable : (typeDesc.IsNullable || typeDesc.IsOptionalValue), Form = (attribute.Form == XmlSchemaForm.None) ? XmlSchemaForm.Qualified : attribute.Form }; CheckForm(accessor.Form, arrayElementNs != accessor.Namespace); CheckNullable(accessor.IsNullable, typeDesc, accessor.Mapping); AddUniqueAccessor(scope, accessor); } } arrayMapping.Elements = (ElementAccessor[]) scope.ToArray(typeof(ElementAccessor)); }
private bool InitializeStructMembers(StructMapping mapping, StructModel model, bool openModel, string typeName, RecursionLimiter limiter) { if (!mapping.IsFullyInitialized) { if (model.TypeDesc.BaseTypeDesc != null) { TypeModel typeModel = this.modelScope.GetTypeModel(model.Type.BaseType, false); if (!(typeModel is StructModel)) { throw new NotSupportedException(Res.GetString("XmlUnsupportedInheritance", new object[] { model.Type.BaseType.FullName })); } StructMapping mapping2 = this.ImportStructLikeMapping((StructModel) typeModel, mapping.Namespace, openModel, null, limiter); int index = limiter.DeferredWorkItems.IndexOf(mapping2); if (index >= 0) { if (!limiter.DeferredWorkItems.Contains(mapping)) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping)); } int num2 = limiter.DeferredWorkItems.Count - 1; if (index < num2) { ImportStructWorkItem item = limiter.DeferredWorkItems[index]; limiter.DeferredWorkItems[index] = limiter.DeferredWorkItems[num2]; limiter.DeferredWorkItems[num2] = item; } return false; } mapping.BaseMapping = mapping2; foreach (AttributeAccessor accessor in mapping.BaseMapping.LocalAttributes.Values) { AddUniqueAccessor(mapping.LocalAttributes, accessor); } if (!mapping.BaseMapping.HasExplicitSequence()) { foreach (ElementAccessor accessor2 in mapping.BaseMapping.LocalElements.Values) { AddUniqueAccessor(mapping.LocalElements, accessor2); } } } ArrayList list = new ArrayList(); TextAccessor text = null; bool hasElements = false; bool isSequence = false; foreach (MemberInfo info in model.GetMemberInfos()) { if ((info.MemberType & (MemberTypes.Property | MemberTypes.Field)) != 0) { XmlAttributes a = this.GetAttributes(info); if (!a.XmlIgnore) { FieldModel fieldModel = model.GetFieldModel(info); if (fieldModel != null) { try { MemberMapping member = this.ImportFieldMapping(model, fieldModel, a, mapping.Namespace, limiter); if ((member != null) && ((mapping.BaseMapping == null) || !mapping.BaseMapping.Declares(member, mapping.TypeName))) { isSequence |= member.IsSequence; AddUniqueAccessor(member, mapping.LocalElements, mapping.LocalAttributes, isSequence); if (member.Text != null) { if (!member.Text.Mapping.TypeDesc.CanBeTextValue && member.Text.Mapping.IsList) { throw new InvalidOperationException(Res.GetString("XmlIllegalTypedTextAttribute", new object[] { typeName, member.Text.Name, member.Text.Mapping.TypeDesc.FullName })); } if (text != null) { throw new InvalidOperationException(Res.GetString("XmlIllegalMultipleText", new object[] { model.Type.FullName })); } text = member.Text; } if (member.Xmlns != null) { if (mapping.XmlnsMember != null) { throw new InvalidOperationException(Res.GetString("XmlMultipleXmlns", new object[] { model.Type.FullName })); } mapping.XmlnsMember = member; } if ((member.Elements != null) && (member.Elements.Length != 0)) { hasElements = true; } list.Add(member); } } catch (Exception exception) { if (((exception is ThreadAbortException) || (exception is StackOverflowException)) || (exception is OutOfMemoryException)) { throw; } throw this.CreateMemberReflectionException(fieldModel, exception); } } } } } mapping.SetContentModel(text, hasElements); if (isSequence) { Hashtable hashtable = new Hashtable(); for (int i = 0; i < list.Count; i++) { MemberMapping mapping4 = (MemberMapping) list[i]; if (mapping4.IsParticle) { if (!mapping4.IsSequence) { throw new InvalidOperationException(Res.GetString("XmlSequenceInconsistent", new object[] { "Order", mapping4.Name })); } if (hashtable[mapping4.SequenceId] != null) { throw new InvalidOperationException(Res.GetString("XmlSequenceUnique", new object[] { mapping4.SequenceId.ToString(CultureInfo.InvariantCulture), "Order", mapping4.Name })); } hashtable[mapping4.SequenceId] = mapping4; } } list.Sort(new MemberMappingComparer()); } mapping.Members = (MemberMapping[]) list.ToArray(typeof(MemberMapping)); if (mapping.BaseMapping == null) { mapping.BaseMapping = this.GetRootMapping(); } if ((mapping.XmlnsMember != null) && mapping.BaseMapping.HasXmlnsMember) { throw new InvalidOperationException(Res.GetString("XmlMultipleXmlns", new object[] { model.Type.FullName })); } this.IncludeTypes(model.Type, limiter); this.typeScope.AddTypeMapping(mapping); if (openModel) { mapping.IsOpenModel = true; } } return true; }
private bool InitializeStructMembers(StructMapping mapping, StructModel model, RecursionLimiter limiter) { if (!mapping.IsFullyInitialized) { if (model.TypeDesc.BaseTypeDesc != null) { StructMapping mapping2 = this.ImportStructLikeMapping((StructModel)this.modelScope.GetTypeModel(model.Type.BaseType, false), limiter); int index = limiter.DeferredWorkItems.IndexOf(mapping.BaseMapping); if (index >= 0) { if (!limiter.DeferredWorkItems.Contains(mapping)) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping)); } int num2 = limiter.DeferredWorkItems.Count - 1; if (index < num2) { ImportStructWorkItem item = limiter.DeferredWorkItems[index]; limiter.DeferredWorkItems[index] = limiter.DeferredWorkItems[num2]; limiter.DeferredWorkItems[num2] = item; } return(false); } mapping.BaseMapping = mapping2; } ArrayList list = new ArrayList(); foreach (MemberInfo info in model.GetMemberInfos()) { if ((info.MemberType & (MemberTypes.Property | MemberTypes.Field)) != 0) { SoapAttributes a = this.GetAttributes(info); if (!a.SoapIgnore) { FieldModel fieldModel = model.GetFieldModel(info); if (fieldModel != null) { MemberMapping member = this.ImportFieldMapping(fieldModel, a, mapping.Namespace, limiter); if (member != null) { if ((!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum) && !member.TypeDesc.IsOptionalValue) { if (model.TypeDesc.IsValueType) { throw new NotSupportedException(Res.GetString("XmlRpcRefsInValueType", new object[] { model.TypeDesc.FullName })); } if (member.TypeDesc.IsValueType) { throw new NotSupportedException(Res.GetString("XmlRpcNestedValueType", new object[] { member.TypeDesc.FullName })); } } if ((mapping.BaseMapping == null) || !mapping.BaseMapping.Declares(member, mapping.TypeName)) { list.Add(member); } } } } } } mapping.Members = (MemberMapping[])list.ToArray(typeof(MemberMapping)); if (mapping.BaseMapping == null) { mapping.BaseMapping = this.GetRootMapping(); } this.IncludeTypes(model.Type, limiter); } return(true); }
private TypeMapping ImportTypeMapping(TypeModel model, string dataType, RecursionLimiter limiter) { if (dataType.Length > 0) { if (!model.TypeDesc.IsPrimitive) { throw new InvalidOperationException(Res.GetString("XmlInvalidDataTypeUsage", new object[] { dataType, "SoapElementAttribute.DataType" })); } TypeDesc typeDesc = this.typeScope.GetTypeDesc(dataType, "http://www.w3.org/2001/XMLSchema"); if (typeDesc == null) { throw new InvalidOperationException(Res.GetString("XmlInvalidXsdDataType", new object[] { dataType, "SoapElementAttribute.DataType", new XmlQualifiedName(dataType, "http://www.w3.org/2001/XMLSchema").ToString() })); } if (model.TypeDesc.FullName != typeDesc.FullName) { throw new InvalidOperationException(Res.GetString("XmlDataTypeMismatch", new object[] { dataType, "SoapElementAttribute.DataType", model.TypeDesc.FullName })); } } if ((this.GetAttributes(model.Type).SoapFlags & ~SoapAttributeFlags.Type) != ((SoapAttributeFlags)0)) { throw new InvalidOperationException(Res.GetString("XmlInvalidTypeAttributes", new object[] { model.Type.FullName })); } switch (model.TypeDesc.Kind) { case TypeKind.Root: case TypeKind.Struct: case TypeKind.Class: { if (!model.TypeDesc.IsOptionalValue) { return(this.ImportStructLikeMapping((StructModel)model, limiter)); } TypeDesc baseTypeDesc = model.TypeDesc.BaseTypeDesc; SoapAttributes attributes = this.GetAttributes(baseTypeDesc.Type); string defaultNs = this.defaultNs; if ((attributes.SoapType != null) && (attributes.SoapType.Namespace != null)) { defaultNs = attributes.SoapType.Namespace; } TypeDesc desc3 = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc : this.typeScope.GetTypeDesc(dataType, "http://www.w3.org/2001/XMLSchema"); string typeName = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc.Name : dataType; TypeMapping baseMapping = this.GetTypeMapping(typeName, defaultNs, desc3); if (baseMapping == null) { baseMapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(baseTypeDesc.Type), dataType, limiter); } return(this.CreateNullableMapping(baseMapping, model.TypeDesc.Type)); } case TypeKind.Primitive: return(this.ImportPrimitiveMapping((PrimitiveModel)model, dataType)); case TypeKind.Enum: return(this.ImportEnumMapping((EnumModel)model)); case TypeKind.Array: case TypeKind.Collection: case TypeKind.Enumerable: return(this.ImportArrayLikeMapping((ArrayModel)model, limiter)); } throw new NotSupportedException(Res.GetString("XmlUnsupportedSoapTypeKind", new object[] { model.TypeDesc.FullName })); }
private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, SoapAttributes a, string ns, XmlSchemaForm form, RecursionLimiter limiter) { Type accessorType = model.FieldType; string accessorName = model.Name; accessor.TypeDesc = _typeScope.GetTypeDesc(accessorType); if (accessor.TypeDesc.IsVoid) { throw new InvalidOperationException(SR.XmlInvalidVoid); } SoapAttributeFlags flags = a.SoapFlags; if ((flags & SoapAttributeFlags.Attribute) == SoapAttributeFlags.Attribute) { if (!accessor.TypeDesc.IsPrimitive && !accessor.TypeDesc.IsEnum) throw new InvalidOperationException(SR.Format(SR.XmlIllegalSoapAttribute, accessorName, accessor.TypeDesc.FullName)); if ((flags & SoapAttributeFlags.Attribute) != flags) throw new InvalidOperationException(SR.XmlInvalidElementAttribute); AttributeAccessor attribute = new AttributeAccessor(); attribute.Name = Accessor.EscapeQName(a.SoapAttribute == null || a.SoapAttribute.AttributeName.Length == 0 ? accessorName : a.SoapAttribute.AttributeName); attribute.Namespace = a.SoapAttribute == null || a.SoapAttribute.Namespace == null ? ns : a.SoapAttribute.Namespace; attribute.Form = XmlSchemaForm.Qualified; // attributes are always qualified since they're only used for encoded soap headers attribute.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(accessorType), (a.SoapAttribute == null ? String.Empty : a.SoapAttribute.DataType), limiter); attribute.Default = GetDefaultValue(model.FieldTypeDesc, a); accessor.Attribute = attribute; accessor.Elements = new ElementAccessor[0]; } else { if ((flags & SoapAttributeFlags.Element) != flags) throw new InvalidOperationException(SR.XmlInvalidElementAttribute); ElementAccessor element = new ElementAccessor(); element.IsSoap = true; element.Name = XmlConvert.EncodeLocalName(a.SoapElement == null || a.SoapElement.ElementName.Length == 0 ? accessorName : a.SoapElement.ElementName); element.Namespace = ns; element.Form = form; element.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(accessorType), (a.SoapElement == null ? String.Empty : a.SoapElement.DataType), limiter); if (a.SoapElement != null) element.IsNullable = a.SoapElement.IsNullable; accessor.Elements = new ElementAccessor[] { element }; } }
private void IncludeType(Type type, RecursionLimiter limiter) { ImportTypeMapping(_modelScope.GetTypeModel(type), limiter); }
private SpecialMapping ImportSpecialMapping(Type type, TypeDesc typeDesc, string ns, ImportContext context, RecursionLimiter limiter) { if (_specials == null) _specials = new Hashtable(); SpecialMapping mapping = (SpecialMapping)_specials[type]; if (mapping != null) { CheckContext(mapping.TypeDesc, context); return mapping; } if (typeDesc.Kind == TypeKind.Serializable) { SerializableMapping serializableMapping = null; // get the schema method info object[] attrs = type.GetTypeInfo().GetCustomAttributes(typeof(XmlSchemaProviderAttribute), false).ToArray(); if (attrs.Length > 0) { // new IXmlSerializable XmlSchemaProviderAttribute provider = (XmlSchemaProviderAttribute)attrs[0]; MethodInfo method = GetMethodFromSchemaProvider(provider, type); serializableMapping = new SerializableMapping(method, provider.IsAny, ns); XmlQualifiedName qname = serializableMapping.XsiType; if (qname != null && !qname.IsEmpty) { serializableMapping.TypeName = qname.Name; serializableMapping.Namespace = qname.Namespace; } serializableMapping.TypeDesc = typeDesc; serializableMapping.Type = type; IncludeTypes(type.GetTypeInfo()); } else { // old IXmlSerializable serializableMapping = new SerializableMapping(); serializableMapping.TypeDesc = typeDesc; serializableMapping.Type = type; } mapping = serializableMapping; } else { mapping = new SpecialMapping(); mapping.TypeDesc = typeDesc; } CheckContext(typeDesc, context); _specials.Add(type, mapping); _typeScope.AddTypeMapping(mapping); return mapping; }
private StructMapping ImportStructLikeMapping(StructModel model, RecursionLimiter limiter) { if (model.TypeDesc.Kind == TypeKind.Root) { return(GetRootMapping()); } SoapAttributes a = GetAttributes(model.Type); string typeNs = _defaultNs; if (a.SoapType != null && a.SoapType.Namespace != null) { typeNs = a.SoapType.Namespace; } string typeName = XsdTypeName(model.Type, a, model.TypeDesc.Name); typeName = XmlConvert.EncodeLocalName(typeName); StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc); if (mapping == null) { mapping = new StructMapping(); mapping.IsSoap = true; mapping.TypeDesc = model.TypeDesc; mapping.Namespace = typeNs; mapping.TypeName = typeName; if (a.SoapType != null) { mapping.IncludeInSchema = a.SoapType.IncludeInSchema; } _typeScope.AddTypeMapping(mapping); _types.Add(typeName, typeNs, mapping); if (limiter.IsExceededLimit) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping)); return(mapping); } limiter.Depth++; InitializeStructMembers(mapping, model, limiter); while (limiter.DeferredWorkItems.Count > 0) { int index = limiter.DeferredWorkItems.Count - 1; ImportStructWorkItem item = limiter.DeferredWorkItems[index]; if (InitializeStructMembers(item.Mapping, item.Model, limiter)) { // // if InitializeStructMembers returns true, then there were *no* changes to the DeferredWorkItems // #if DEBUG // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe if (index != limiter.DeferredWorkItems.Count - 1) { throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "DeferredWorkItems.Count have changed")); } if (item != limiter.DeferredWorkItems[index]) { throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "DeferredWorkItems.Top have changed")); } #endif // Remove the last work item limiter.DeferredWorkItems.RemoveAt(index); } } limiter.Depth--; } return(mapping); }
private MemberMapping ImportFieldMapping(FieldModel model, SoapAttributes a, string ns, RecursionLimiter limiter) { if (a.SoapIgnore) { return(null); } MemberMapping accessor = new MemberMapping { IsSoap = true, Name = model.Name, CheckShouldPersist = model.CheckShouldPersist, CheckSpecified = model.CheckSpecified, ReadOnly = model.ReadOnly }; this.ImportAccessorMapping(accessor, model, a, ns, XmlSchemaForm.Unqualified, limiter); return(accessor); }
private MemberMapping ImportMemberMapping(XmlReflectionMember xmlReflectionMember, string ns, XmlReflectionMember[] xmlReflectionMembers, XmlSchemaForm form, RecursionLimiter limiter) { SoapAttributes a = xmlReflectionMember.SoapAttributes; if (a.SoapIgnore) { return(null); } MemberMapping member = new MemberMapping(); member.IsSoap = true; member.Name = xmlReflectionMember.MemberName; bool checkSpecified = XmlReflectionImporter.FindSpecifiedMember(xmlReflectionMember.MemberName, xmlReflectionMembers) != null; FieldModel model = new FieldModel(xmlReflectionMember.MemberName, xmlReflectionMember.MemberType, _typeScope.GetTypeDesc(xmlReflectionMember.MemberType), checkSpecified, false); member.CheckShouldPersist = model.CheckShouldPersist; member.CheckSpecified = model.CheckSpecified; member.ReadOnly = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor; ImportAccessorMapping(member, model, a, ns, form, limiter); if (xmlReflectionMember.OverrideIsNullable) { member.Elements[0].IsNullable = false; } return(member); }
MembersMapping ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, string ns, bool hasWrapperElement, bool rpc, bool openModel, RecursionLimiter limiter) { MembersMapping members = new MembersMapping(); members.TypeDesc = typeScope.GetTypeDesc(typeof(object[])); MemberMapping[] mappings = new MemberMapping[xmlReflectionMembers.Length]; NameTable elements = new NameTable(); NameTable attributes = new NameTable(); TextAccessor textAccessor = null; bool isSequence = false; for (int i = 0; i < mappings.Length; i++) { try { MemberMapping mapping = ImportMemberMapping(xmlReflectionMembers[i], ns, xmlReflectionMembers, rpc, openModel, limiter); if (!hasWrapperElement) { if (mapping.Attribute != null) { if (rpc) { throw new InvalidOperationException(Res.GetString(Res.XmlRpcLitAttributeAttributes)); } else { throw new InvalidOperationException(Res.GetString(Res.XmlInvalidAttributeType, "XmlAttribute")); } } } if (rpc && xmlReflectionMembers[i].IsReturnValue) { if (i > 0) throw new InvalidOperationException(Res.GetString(Res.XmlInvalidReturnPosition)); mapping.IsReturnValue = true; } mappings[i] = mapping; isSequence |= mapping.IsSequence; if (!xmlReflectionMembers[i].XmlAttributes.XmlIgnore) { // add All memeber accessors to the scope accessors AddUniqueAccessor(mapping, elements, attributes, isSequence); } mappings[i] = mapping; if (mapping.Text != null) { if (textAccessor != null) { throw new InvalidOperationException(Res.GetString(Res.XmlIllegalMultipleTextMembers)); } textAccessor = mapping.Text; } if (mapping.Xmlns != null) { if (members.XmlnsMember != null) throw new InvalidOperationException(Res.GetString(Res.XmlMultipleXmlnsMembers)); members.XmlnsMember = mapping; } } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } throw CreateReflectionException(xmlReflectionMembers[i].MemberName, e); } } if (isSequence) { throw new InvalidOperationException(Res.GetString(Res.XmlSequenceMembers, "Order")); } members.Members = mappings; members.HasWrapperElement = hasWrapperElement; return members; }
private MembersMapping ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, string ns, bool hasWrapperElement, bool writeAccessors, bool validateWrapperElement, RecursionLimiter limiter) { MembersMapping mapping = new MembersMapping { TypeDesc = this.typeScope.GetTypeDesc(typeof(object[])) }; MemberMapping[] mappingArray = new MemberMapping[xmlReflectionMembers.Length]; for (int i = 0; i < mappingArray.Length; i++) { try { XmlReflectionMember xmlReflectionMember = xmlReflectionMembers[i]; MemberMapping mapping2 = this.ImportMemberMapping(xmlReflectionMember, ns, xmlReflectionMembers, hasWrapperElement ? XmlSchemaForm.Unqualified : XmlSchemaForm.Qualified, limiter); if (xmlReflectionMember.IsReturnValue && writeAccessors) { if (i > 0) { throw new InvalidOperationException(Res.GetString("XmlInvalidReturnPosition")); } mapping2.IsReturnValue = true; } mappingArray[i] = mapping2; } catch (Exception exception) { if (((exception is ThreadAbortException) || (exception is StackOverflowException)) || (exception is OutOfMemoryException)) { throw; } throw this.ReflectionException(xmlReflectionMembers[i].MemberName, exception); } } mapping.Members = mappingArray; mapping.HasWrapperElement = hasWrapperElement; if (hasWrapperElement) { mapping.ValidateRpcWrapperElement = validateWrapperElement; } mapping.WriteAccessors = writeAccessors; mapping.IsSoap = true; if (hasWrapperElement && !writeAccessors) { mapping.Namespace = ns; } return(mapping); }
void IncludeType(Type type, RecursionLimiter limiter) { int previousNestingLevel = arrayNestingLevel; XmlArrayItemAttributes previousArrayItemAttributes = savedArrayItemAttributes; string previousArrayNamespace = savedArrayNamespace; arrayNestingLevel = 0; savedArrayItemAttributes = null; savedArrayNamespace = null; TypeMapping mapping = ImportTypeMapping(modelScope.GetTypeModel(type), defaultNs, ImportContext.Element, string.Empty, null, limiter); if (mapping.IsAnonymousType && !mapping.TypeDesc.IsSpecial) { //XmlAnonymousInclude=Cannot include anonymous type '{0}'. throw new InvalidOperationException(Res.GetString(Res.XmlAnonymousInclude, type.FullName)); } arrayNestingLevel = previousNestingLevel; savedArrayItemAttributes = previousArrayItemAttributes; savedArrayNamespace = previousArrayNamespace; }
private TypeMapping ImportTypeMapping(TypeModel model, string dataType, RecursionLimiter limiter) { if (dataType.Length > 0) { if (!model.TypeDesc.IsPrimitive) { throw new InvalidOperationException(SR.Format(SR.XmlInvalidDataTypeUsage, dataType, "SoapElementAttribute.DataType")); } TypeDesc td = _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace); if (td == null) { throw new InvalidOperationException(SR.Format(SR.XmlInvalidXsdDataType, dataType, "SoapElementAttribute.DataType", new XmlQualifiedName(dataType, XmlSchema.Namespace).ToString())); } if (model.TypeDesc.FullName != td.FullName) { throw new InvalidOperationException(SR.Format(SR.XmlDataTypeMismatch, dataType, "SoapElementAttribute.DataType", model.TypeDesc.FullName)); } } SoapAttributes a = GetAttributes(model.Type); if ((a.SoapFlags & ~SoapAttributeFlags.Type) != 0) throw new InvalidOperationException(SR.Format(SR.XmlInvalidTypeAttributes, model.Type.FullName)); switch (model.TypeDesc.Kind) { case TypeKind.Enum: return ImportEnumMapping((EnumModel)model); case TypeKind.Primitive: return ImportPrimitiveMapping((PrimitiveModel)model, dataType); case TypeKind.Array: case TypeKind.Collection: case TypeKind.Enumerable: return ImportArrayLikeMapping((ArrayModel)model, limiter); case TypeKind.Root: case TypeKind.Class: case TypeKind.Struct: if (model.TypeDesc.IsOptionalValue) { TypeDesc baseTypeDesc = model.TypeDesc.BaseTypeDesc; SoapAttributes baseAttributes = GetAttributes(baseTypeDesc.Type); string typeNs = _defaultNs; if (baseAttributes.SoapType != null && baseAttributes.SoapType.Namespace != null) typeNs = baseAttributes.SoapType.Namespace; TypeDesc valueTypeDesc = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc : _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace); string xsdTypeName = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc.Name : dataType; TypeMapping baseMapping = GetTypeMapping(xsdTypeName, typeNs, valueTypeDesc); if (baseMapping == null) baseMapping = ImportTypeMapping(_modelScope.GetTypeModel(baseTypeDesc.Type), dataType, limiter); return CreateNullableMapping(baseMapping, model.TypeDesc.Type); } else { return ImportStructLikeMapping((StructModel)model, limiter); } default: throw new NotSupportedException(SR.Format(SR.XmlUnsupportedSoapTypeKind, model.TypeDesc.FullName)); } }
MemberMapping ImportMemberMapping(XmlReflectionMember xmlReflectionMember, string ns, XmlReflectionMember[] xmlReflectionMembers, bool rpc, bool openModel, RecursionLimiter limiter) { XmlSchemaForm form = rpc ? XmlSchemaForm.Unqualified : XmlSchemaForm.Qualified; XmlAttributes a = xmlReflectionMember.XmlAttributes; TypeDesc typeDesc = typeScope.GetTypeDesc(xmlReflectionMember.MemberType); if (a.XmlFlags == 0) { if (typeDesc.IsArrayLike) { XmlArrayAttribute xmlArray = CreateArrayAttribute(typeDesc); xmlArray.ElementName = xmlReflectionMember.MemberName; xmlArray.Namespace = rpc ? null : ns; xmlArray.Form = form; a.XmlArray = xmlArray; } else { XmlElementAttribute xmlElement = CreateElementAttribute(typeDesc); // If there is no metadata specified on a parameter, then see if someone used // an XmlRoot attribute on the struct or class. if (typeDesc.IsStructLike) { XmlAttributes structAttrs = new XmlAttributes(xmlReflectionMember.MemberType); if (structAttrs.XmlRoot != null) { if (structAttrs.XmlRoot.ElementName.Length > 0) xmlElement.ElementName = structAttrs.XmlRoot.ElementName; if (rpc) { xmlElement.Namespace = null; if (structAttrs.XmlRoot.IsNullableSpecified) xmlElement.IsNullable = structAttrs.XmlRoot.IsNullable; } else { xmlElement.Namespace = structAttrs.XmlRoot.Namespace; xmlElement.IsNullable = structAttrs.XmlRoot.IsNullable; } } } if (xmlElement.ElementName.Length == 0) xmlElement.ElementName = xmlReflectionMember.MemberName; if (xmlElement.Namespace == null && !rpc) xmlElement.Namespace = ns; xmlElement.Form = form; a.XmlElements.Add(xmlElement); } } else if (a.XmlRoot != null) { CheckNullable(a.XmlRoot.IsNullable, typeDesc, null); } MemberMapping member = new MemberMapping(); member.Name = xmlReflectionMember.MemberName; bool checkSpecified = FindSpecifiedMember(xmlReflectionMember.MemberName, xmlReflectionMembers) != null; FieldModel model = new FieldModel(xmlReflectionMember.MemberName, xmlReflectionMember.MemberType, typeScope.GetTypeDesc(xmlReflectionMember.MemberType), checkSpecified, false); member.CheckShouldPersist = model.CheckShouldPersist; member.CheckSpecified = model.CheckSpecified; member.ReadOnly = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor; Type choiceIdentifierType = null; if (a.XmlChoiceIdentifier != null) { choiceIdentifierType = GetChoiceIdentifierType(a.XmlChoiceIdentifier, xmlReflectionMembers, typeDesc.IsArrayLike, model.Name); } ImportAccessorMapping(member, model, a, ns, choiceIdentifierType, rpc, openModel, limiter); if (xmlReflectionMember.OverrideIsNullable && member.Elements.Length > 0) member.Elements[0].IsNullable = false; return member; }
private bool InitializeStructMembers(StructMapping mapping, StructModel model, RecursionLimiter limiter) { if (mapping.IsFullyInitialized) return true; if (model.TypeDesc.BaseTypeDesc != null) { StructMapping baseMapping = ImportStructLikeMapping((StructModel)_modelScope.GetTypeModel(model.Type.GetTypeInfo().BaseType, false), limiter); // check to see if the import of the baseMapping was deffered int baseIndex = limiter.DeferredWorkItems.IndexOf(mapping.BaseMapping); if (baseIndex < 0) { mapping.BaseMapping = baseMapping; } else { // the import of the baseMapping was deffered, make sure that the derived mappings is deffered as well if (!limiter.DeferredWorkItems.Contains(mapping)) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping)); } // make sure that baseMapping get processed before the derived int top = limiter.DeferredWorkItems.Count - 1; if (baseIndex < top) { ImportStructWorkItem baseMappingWorkItem = limiter.DeferredWorkItems[baseIndex]; limiter.DeferredWorkItems[baseIndex] = limiter.DeferredWorkItems[top]; limiter.DeferredWorkItems[top] = baseMappingWorkItem; } return false; } } ArrayList members = new ArrayList(); foreach (MemberInfo memberInfo in model.GetMemberInfos()) { if (!(memberInfo is FieldInfo) && !(memberInfo is PropertyInfo)) continue; SoapAttributes memberAttrs = GetAttributes(memberInfo); if (memberAttrs.SoapIgnore) continue; FieldModel fieldModel = model.GetFieldModel(memberInfo); if (fieldModel == null) continue; MemberMapping member = ImportFieldMapping(fieldModel, memberAttrs, mapping.Namespace, limiter); if (member == null) continue; if (!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum && !member.TypeDesc.IsOptionalValue) { if (model.TypeDesc.IsValueType) throw new NotSupportedException(SR.Format(SR.XmlRpcRefsInValueType, model.TypeDesc.FullName)); if (member.TypeDesc.IsValueType) throw new NotSupportedException(SR.Format(SR.XmlRpcNestedValueType, member.TypeDesc.FullName)); } if (mapping.BaseMapping != null) { if (mapping.BaseMapping.Declares(member, mapping.TypeName)) continue; } members.Add(member); } mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping)); if (mapping.BaseMapping == null) mapping.BaseMapping = GetRootMapping(); IncludeTypes(model.Type.GetTypeInfo(), limiter); return true; }
MemberMapping ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, string ns, RecursionLimiter limiter) { MemberMapping member = new MemberMapping(); member.Name = model.Name; member.CheckShouldPersist = model.CheckShouldPersist; member.CheckSpecified = model.CheckSpecified; member.MemberInfo = model.MemberInfo; member.CheckSpecifiedMemberInfo = model.CheckSpecifiedMemberInfo; member.CheckShouldPersistMethodInfo = model.CheckShouldPersistMethodInfo; member.ReadOnly = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor; Type choiceIdentifierType = null; if (a.XmlChoiceIdentifier != null) { choiceIdentifierType = GetChoiceIdentifierType(a.XmlChoiceIdentifier, parent, model.FieldTypeDesc.IsArrayLike, model.Name); } ImportAccessorMapping(member, model, a, ns, choiceIdentifierType, false, false, limiter); return member; }
private MembersMapping ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, string ns, bool hasWrapperElement, bool writeAccessors, bool validateWrapperElement, RecursionLimiter limiter) { MembersMapping members = new MembersMapping(); members.TypeDesc = _typeScope.GetTypeDesc(typeof(object[])); MemberMapping[] mappings = new MemberMapping[xmlReflectionMembers.Length]; for (int i = 0; i < mappings.Length; i++) { try { XmlReflectionMember member = xmlReflectionMembers[i]; MemberMapping mapping = ImportMemberMapping(member, ns, xmlReflectionMembers, hasWrapperElement ? XmlSchemaForm.Unqualified : XmlSchemaForm.Qualified, limiter); if (member.IsReturnValue && writeAccessors) { // no special treatment for return values with doc/enc if (i > 0) throw new InvalidOperationException(SR.XmlInvalidReturnPosition); mapping.IsReturnValue = true; } mappings[i] = mapping; } catch (Exception e) { if (e is OutOfMemoryException) { throw; } throw ReflectionException(xmlReflectionMembers[i].MemberName, e); } } members.Members = mappings; members.HasWrapperElement = hasWrapperElement; if (hasWrapperElement) { members.ValidateRpcWrapperElement = validateWrapperElement; } members.WriteAccessors = writeAccessors; members.IsSoap = true; if (hasWrapperElement && !writeAccessors) members.Namespace = ns; return members; }
void CreateArrayElementsFromAttributes(ArrayMapping arrayMapping, XmlArrayItemAttributes attributes, Type arrayElementType, string arrayElementNs, RecursionLimiter limiter) { NameTable arrayItemElements = new NameTable(); // xmlelementname + xmlns -> ElementAccessor for (int i = 0; attributes != null && i < attributes.Count; i++) { XmlArrayItemAttribute xmlArrayItem = attributes[i]; if (xmlArrayItem.NestingLevel != arrayNestingLevel) continue; Type targetType = xmlArrayItem.Type != null ? xmlArrayItem.Type : arrayElementType; TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType); ElementAccessor arrayItemElement = new ElementAccessor(); arrayItemElement.Namespace = xmlArrayItem.Namespace == null ? arrayElementNs : xmlArrayItem.Namespace; arrayItemElement.Mapping = ImportTypeMapping(modelScope.GetTypeModel(targetType), arrayItemElement.Namespace, ImportContext.Element, xmlArrayItem.DataType, null, limiter); arrayItemElement.Name = xmlArrayItem.ElementName.Length == 0 ? arrayItemElement.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(xmlArrayItem.ElementName); arrayItemElement.IsNullable = xmlArrayItem.IsNullableSpecified ? xmlArrayItem.IsNullable : targetTypeDesc.IsNullable || targetTypeDesc.IsOptionalValue; arrayItemElement.Form = xmlArrayItem.Form == XmlSchemaForm.None ? XmlSchemaForm.Qualified : xmlArrayItem.Form; CheckForm(arrayItemElement.Form, arrayElementNs != arrayItemElement.Namespace); CheckNullable(arrayItemElement.IsNullable, targetTypeDesc, arrayItemElement.Mapping); AddUniqueAccessor(arrayItemElements, arrayItemElement); } arrayMapping.Elements = (ElementAccessor[])arrayItemElements.ToArray(typeof(ElementAccessor)); }
private MemberMapping ImportFieldMapping(FieldModel model, SoapAttributes a, string ns, RecursionLimiter limiter) { if (a.SoapIgnore) return null; MemberMapping member = new MemberMapping(); member.IsSoap = true; member.Name = model.Name; member.CheckShouldPersist = model.CheckShouldPersist; member.CheckSpecified = model.CheckSpecified; member.MemberInfo = model.MemberInfo; member.CheckSpecifiedMemberInfo = model.CheckSpecifiedMemberInfo; member.CheckShouldPersistMethodInfo = model.CheckShouldPersistMethodInfo; member.ReadOnly = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor; ImportAccessorMapping(member, model, a, ns, XmlSchemaForm.Unqualified, limiter); return member; }
void ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, string ns, Type choiceIdentifierType, bool rpc, bool openModel, RecursionLimiter limiter) { XmlSchemaForm elementFormDefault = XmlSchemaForm.Qualified; int previousNestingLevel = arrayNestingLevel; int sequenceId = -1; XmlArrayItemAttributes previousArrayItemAttributes = savedArrayItemAttributes; string previousArrayNamespace = savedArrayNamespace; arrayNestingLevel = 0; savedArrayItemAttributes = null; savedArrayNamespace = null; Type accessorType = model.FieldType; string accessorName = model.Name; ArrayList elementList = new ArrayList(); NameTable elements = new NameTable(); accessor.TypeDesc = typeScope.GetTypeDesc(accessorType); XmlAttributeFlags flags = a.XmlFlags; accessor.Ignore = a.XmlIgnore; if (rpc) CheckTopLevelAttributes(a, accessorName); else CheckAmbiguousChoice(a, accessorType, accessorName); XmlAttributeFlags elemFlags = XmlAttributeFlags.Elements | XmlAttributeFlags.Text | XmlAttributeFlags.AnyElements | XmlAttributeFlags.ChoiceIdentifier; XmlAttributeFlags attrFlags = XmlAttributeFlags.Attribute | XmlAttributeFlags.AnyAttribute; XmlAttributeFlags arrayFlags = XmlAttributeFlags.Array | XmlAttributeFlags.ArrayItems; // special case for byte[]. It can be a primitive (base64Binary or hexBinary), or it can // be an array of bytes. Our default is primitive; specify [XmlArray] to get array behavior. if ((flags & arrayFlags) != 0 && accessorType == typeof(byte[])) accessor.TypeDesc = typeScope.GetArrayTypeDesc(accessorType); if (a.XmlChoiceIdentifier != null) { accessor.ChoiceIdentifier = new ChoiceIdentifierAccessor(); accessor.ChoiceIdentifier.MemberName = a.XmlChoiceIdentifier.MemberName; accessor.ChoiceIdentifier.MemberInfo = a.XmlChoiceIdentifier.MemberInfo; accessor.ChoiceIdentifier.Mapping = ImportTypeMapping(modelScope.GetTypeModel(choiceIdentifierType), ns, ImportContext.Element, String.Empty, null, limiter); CheckChoiceIdentifierMapping((EnumMapping)accessor.ChoiceIdentifier.Mapping); } if (accessor.TypeDesc.IsArrayLike) { Type arrayElementType = TypeScope.GetArrayElementType(accessorType, model.FieldTypeDesc.FullName + "." + model.Name); if ((flags & attrFlags) != 0) { if ((flags & attrFlags) != flags) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttributesArrayAttribute)); if (a.XmlAttribute != null && !accessor.TypeDesc.ArrayElementTypeDesc.IsPrimitive && !accessor.TypeDesc.ArrayElementTypeDesc.IsEnum) { if (accessor.TypeDesc.ArrayElementTypeDesc.Kind == TypeKind.Serializable) { throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttrOrTextInterface, accessorName, accessor.TypeDesc.ArrayElementTypeDesc.FullName, typeof(IXmlSerializable).Name)); } else { throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttrOrText, accessorName, accessor.TypeDesc.ArrayElementTypeDesc.FullName)); } } bool isList = a.XmlAttribute != null && (accessor.TypeDesc.ArrayElementTypeDesc.IsPrimitive || accessor.TypeDesc.ArrayElementTypeDesc.IsEnum); if (a.XmlAnyAttribute != null) { a.XmlAttribute = new XmlAttributeAttribute(); } AttributeAccessor attribute = new AttributeAccessor(); Type targetType = a.XmlAttribute.Type == null ? arrayElementType : a.XmlAttribute.Type; TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType); attribute.Name = Accessor.EscapeQName(a.XmlAttribute.AttributeName.Length == 0 ? accessorName : a.XmlAttribute.AttributeName); attribute.Namespace = a.XmlAttribute.Namespace == null ? ns : a.XmlAttribute.Namespace; attribute.Form = a.XmlAttribute.Form; if (attribute.Form == XmlSchemaForm.None && ns != attribute.Namespace) { attribute.Form = XmlSchemaForm.Qualified; } attribute.CheckSpecial(); CheckForm(attribute.Form, ns != attribute.Namespace); attribute.Mapping = ImportTypeMapping(modelScope.GetTypeModel(targetType), ns, ImportContext.Attribute, a.XmlAttribute.DataType, null, isList, false, limiter); attribute.IsList = isList; attribute.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); attribute.Any = (a.XmlAnyAttribute != null); if (attribute.Form == XmlSchemaForm.Qualified && attribute.Namespace != ns) { if (xsdAttributes == null) xsdAttributes = new NameTable(); attribute = (AttributeAccessor)ReconcileAccessor(attribute, xsdAttributes); } accessor.Attribute = attribute; } else if ((flags & elemFlags) != 0) { if ((flags & elemFlags) != flags) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalElementsArrayAttribute)); if (a.XmlText != null) { TextAccessor text = new TextAccessor(); Type targetType = a.XmlText.Type == null ? arrayElementType : a.XmlText.Type; TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType); text.Name = accessorName; // unused except to make more helpful error messages text.Mapping = ImportTypeMapping(modelScope.GetTypeModel(targetType), ns, ImportContext.Text, a.XmlText.DataType, null, true, false, limiter); if (!(text.Mapping is SpecialMapping) && targetTypeDesc != typeScope.GetTypeDesc(typeof(string))) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalArrayTextAttribute, accessorName)); accessor.Text = text; } if (a.XmlText == null && a.XmlElements.Count == 0 && a.XmlAnyElements.Count == 0) a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc)); for (int i = 0; i < a.XmlElements.Count; i++) { XmlElementAttribute xmlElement = a.XmlElements[i]; Type targetType = xmlElement.Type == null ? arrayElementType : xmlElement.Type; TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType); TypeModel typeModel = modelScope.GetTypeModel(targetType); ElementAccessor element = new ElementAccessor(); element.Namespace = rpc ? null : xmlElement.Namespace == null ? ns : xmlElement.Namespace; element.Mapping = ImportTypeMapping(typeModel, rpc ? ns : element.Namespace, ImportContext.Element, xmlElement.DataType, null, limiter); if (a.XmlElements.Count == 1) { element.Name = XmlConvert.EncodeLocalName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName); //element.IsUnbounded = element.Mapping is ArrayMapping; } else { element.Name = xmlElement.ElementName.Length == 0 ? element.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(xmlElement.ElementName); } element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); if (xmlElement.IsNullableSpecified && !xmlElement.IsNullable && typeModel.TypeDesc.IsOptionalValue) //XmlInvalidNotNullable=IsNullable may not be set to 'false' for a Nullable<{0}> type. Consider using '{0}' type or removing the IsNullable property from the XmlElement attribute. throw new InvalidOperationException(Res.GetString(Res.XmlInvalidNotNullable, typeModel.TypeDesc.BaseTypeDesc.FullName, "XmlElement")); element.IsNullable = xmlElement.IsNullableSpecified ? xmlElement.IsNullable : typeModel.TypeDesc.IsOptionalValue; element.Form = rpc ? XmlSchemaForm.Unqualified : xmlElement.Form == XmlSchemaForm.None ? elementFormDefault : xmlElement.Form; CheckNullable(element.IsNullable, targetTypeDesc, element.Mapping); if (!rpc) { CheckForm(element.Form, ns != element.Namespace); element = ReconcileLocalAccessor(element, ns); } if (xmlElement.Order != -1) { if (xmlElement.Order != sequenceId && sequenceId != -1) throw new InvalidOperationException(Res.GetString(Res.XmlSequenceMatch, "Order")); sequenceId = xmlElement.Order; } AddUniqueAccessor(elements, element); elementList.Add(element); } NameTable anys = new NameTable(); for (int i = 0; i < a.XmlAnyElements.Count; i++) { XmlAnyElementAttribute xmlAnyElement = a.XmlAnyElements[i]; Type targetType = typeof(IXmlSerializable).IsAssignableFrom(arrayElementType) ? arrayElementType : typeof(XmlNode).IsAssignableFrom(arrayElementType) ? arrayElementType : typeof(XmlElement); if (!arrayElementType.IsAssignableFrom(targetType)) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAnyElement, arrayElementType.FullName)); string anyName = xmlAnyElement.Name.Length == 0 ? xmlAnyElement.Name : XmlConvert.EncodeLocalName(xmlAnyElement.Name); string anyNs = xmlAnyElement.NamespaceSpecified ? xmlAnyElement.Namespace : null; if (anys[anyName, anyNs] != null) { // ignore duplicate anys continue; } anys[anyName, anyNs] = xmlAnyElement; if (elements[anyName, (anyNs == null ? ns : anyNs)] != null) { throw new InvalidOperationException(Res.GetString(Res.XmlAnyElementDuplicate, accessorName, xmlAnyElement.Name, xmlAnyElement.Namespace == null ? "null" : xmlAnyElement.Namespace)); } ElementAccessor element = new ElementAccessor(); element.Name = anyName; element.Namespace = anyNs == null ? ns : anyNs; element.Any = true; element.AnyNamespaces = anyNs; TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType); TypeModel typeModel = modelScope.GetTypeModel(targetType); if (element.Name.Length > 0) typeModel.TypeDesc.IsMixed = true; element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, String.Empty, null, limiter); element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); element.IsNullable = false; element.Form = elementFormDefault; CheckNullable(element.IsNullable, targetTypeDesc, element.Mapping); if (!rpc) { CheckForm(element.Form, ns != element.Namespace); element = ReconcileLocalAccessor(element, ns); } elements.Add(element.Name, element.Namespace, element); elementList.Add(element); if (xmlAnyElement.Order != -1) { if (xmlAnyElement.Order != sequenceId && sequenceId != -1) throw new InvalidOperationException(Res.GetString(Res.XmlSequenceMatch, "Order")); sequenceId = xmlAnyElement.Order; } } } else { if ((flags & arrayFlags) != 0) { if ((flags & arrayFlags) != flags) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalArrayArrayAttribute)); } TypeDesc arrayElementTypeDesc = typeScope.GetTypeDesc(arrayElementType); if (a.XmlArray == null) a.XmlArray = CreateArrayAttribute(accessor.TypeDesc); if (CountAtLevel(a.XmlArrayItems, arrayNestingLevel) == 0) a.XmlArrayItems.Add(CreateArrayItemAttribute(arrayElementTypeDesc, arrayNestingLevel)); ElementAccessor arrayElement = new ElementAccessor(); arrayElement.Name = XmlConvert.EncodeLocalName(a.XmlArray.ElementName.Length == 0 ? accessorName : a.XmlArray.ElementName); arrayElement.Namespace = rpc ? null : a.XmlArray.Namespace == null ? ns : a.XmlArray.Namespace; savedArrayItemAttributes = a.XmlArrayItems; savedArrayNamespace = arrayElement.Namespace; ArrayMapping arrayMapping = ImportArrayLikeMapping(modelScope.GetArrayModel(accessorType), ns, limiter); arrayElement.Mapping = arrayMapping; arrayElement.IsNullable = a.XmlArray.IsNullable; arrayElement.Form = rpc ? XmlSchemaForm.Unqualified : a.XmlArray.Form == XmlSchemaForm.None ? elementFormDefault : a.XmlArray.Form; sequenceId = a.XmlArray.Order; CheckNullable(arrayElement.IsNullable, accessor.TypeDesc, arrayElement.Mapping); if (!rpc) { CheckForm(arrayElement.Form, ns != arrayElement.Namespace); arrayElement = ReconcileLocalAccessor(arrayElement, ns); } savedArrayItemAttributes = null; savedArrayNamespace = null; AddUniqueAccessor(elements, arrayElement); elementList.Add(arrayElement); } } else if (!accessor.TypeDesc.IsVoid) { XmlAttributeFlags allFlags = XmlAttributeFlags.Elements | XmlAttributeFlags.Text | XmlAttributeFlags.Attribute | XmlAttributeFlags.AnyElements | XmlAttributeFlags.ChoiceIdentifier | XmlAttributeFlags.XmlnsDeclarations; if ((flags & allFlags) != flags) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttribute)); if (accessor.TypeDesc.IsPrimitive || accessor.TypeDesc.IsEnum) { if (a.XmlAnyElements.Count > 0) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAnyElement, accessor.TypeDesc.FullName)); if (a.XmlAttribute != null) { if (a.XmlElements.Count > 0) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttribute)); if (a.XmlAttribute.Type != null) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalType, "XmlAttribute")); AttributeAccessor attribute = new AttributeAccessor(); attribute.Name = Accessor.EscapeQName(a.XmlAttribute.AttributeName.Length == 0 ? accessorName : a.XmlAttribute.AttributeName); attribute.Namespace = a.XmlAttribute.Namespace == null ? ns : a.XmlAttribute.Namespace; attribute.Form = a.XmlAttribute.Form; if (attribute.Form == XmlSchemaForm.None && ns != attribute.Namespace) { attribute.Form = XmlSchemaForm.Qualified; } attribute.CheckSpecial(); CheckForm(attribute.Form, ns != attribute.Namespace); attribute.Mapping = ImportTypeMapping(modelScope.GetTypeModel(accessorType), ns, ImportContext.Attribute, a.XmlAttribute.DataType, null, limiter); attribute.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); attribute.Any = a.XmlAnyAttribute != null; if (attribute.Form == XmlSchemaForm.Qualified && attribute.Namespace != ns) { if (xsdAttributes == null) xsdAttributes = new NameTable(); attribute = (AttributeAccessor)ReconcileAccessor(attribute, xsdAttributes); } accessor.Attribute = attribute; } else { if (a.XmlText != null) { if (a.XmlText.Type != null && a.XmlText.Type != accessorType) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalType, "XmlText")); TextAccessor text = new TextAccessor(); text.Name = accessorName; // unused except to make more helpful error messages text.Mapping = ImportTypeMapping(modelScope.GetTypeModel(accessorType), ns, ImportContext.Text, a.XmlText.DataType, null, limiter); accessor.Text = text; } else if (a.XmlElements.Count == 0) { a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc)); } for (int i = 0; i < a.XmlElements.Count; i++) { XmlElementAttribute xmlElement = a.XmlElements[i]; if (xmlElement.Type != null) { if (typeScope.GetTypeDesc(xmlElement.Type) != accessor.TypeDesc) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalType, "XmlElement")); } ElementAccessor element = new ElementAccessor(); element.Name = XmlConvert.EncodeLocalName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName); element.Namespace = rpc ? null : xmlElement.Namespace == null ? ns : xmlElement.Namespace; TypeModel typeModel = modelScope.GetTypeModel(accessorType); element.Mapping = ImportTypeMapping(typeModel, rpc ? ns : element.Namespace, ImportContext.Element, xmlElement.DataType, null, limiter); if (element.Mapping.TypeDesc.Kind == TypeKind.Node) { element.Any = true; } element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); if (xmlElement.IsNullableSpecified && !xmlElement.IsNullable && typeModel.TypeDesc.IsOptionalValue) //XmlInvalidNotNullable=IsNullable may not be set to 'false' for a Nullable<{0}> type. Consider using '{0}' type or removing the IsNullable property from the XmlElement attribute. throw new InvalidOperationException(Res.GetString(Res.XmlInvalidNotNullable, typeModel.TypeDesc.BaseTypeDesc.FullName, "XmlElement")); element.IsNullable = xmlElement.IsNullableSpecified ? xmlElement.IsNullable : typeModel.TypeDesc.IsOptionalValue; element.Form = rpc ? XmlSchemaForm.Unqualified : xmlElement.Form == XmlSchemaForm.None ? elementFormDefault : xmlElement.Form; CheckNullable(element.IsNullable, accessor.TypeDesc, element.Mapping); if (!rpc) { CheckForm(element.Form, ns != element.Namespace); element = ReconcileLocalAccessor(element, ns); } if (xmlElement.Order != -1) { if (xmlElement.Order != sequenceId && sequenceId != -1) throw new InvalidOperationException(Res.GetString(Res.XmlSequenceMatch, "Order")); sequenceId = xmlElement.Order; } AddUniqueAccessor(elements, element); elementList.Add(element); } } } else if (a.Xmlns) { if (flags != XmlAttributeFlags.XmlnsDeclarations) throw new InvalidOperationException(Res.GetString(Res.XmlSoleXmlnsAttribute)); if (accessorType != typeof(XmlSerializerNamespaces)) { throw new InvalidOperationException(Res.GetString(Res.XmlXmlnsInvalidType, accessorName, accessorType.FullName, typeof(XmlSerializerNamespaces).FullName)); } accessor.Xmlns = new XmlnsAccessor(); accessor.Ignore = true; } else { if (a.XmlAttribute != null || a.XmlText != null) { if (accessor.TypeDesc.Kind == TypeKind.Serializable) { throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttrOrTextInterface, accessorName, accessor.TypeDesc.FullName, typeof(IXmlSerializable).Name)); } else { throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttrOrText, accessorName, accessor.TypeDesc)); } } if (a.XmlElements.Count == 0 && a.XmlAnyElements.Count == 0) a.XmlElements.Add(CreateElementAttribute(accessor.TypeDesc)); for (int i = 0; i < a.XmlElements.Count; i++) { XmlElementAttribute xmlElement = a.XmlElements[i]; Type targetType = xmlElement.Type == null ? accessorType : xmlElement.Type; TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType); ElementAccessor element = new ElementAccessor(); TypeModel typeModel = modelScope.GetTypeModel(targetType); element.Namespace = rpc ? null : xmlElement.Namespace == null ? ns : xmlElement.Namespace; element.Mapping = ImportTypeMapping(typeModel, rpc ? ns : element.Namespace, ImportContext.Element, xmlElement.DataType, null, false, openModel, limiter); if (a.XmlElements.Count == 1) { element.Name = XmlConvert.EncodeLocalName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName); } else { element.Name = xmlElement.ElementName.Length == 0 ? element.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(xmlElement.ElementName); } element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); if (xmlElement.IsNullableSpecified && !xmlElement.IsNullable && typeModel.TypeDesc.IsOptionalValue) //XmlInvalidNotNullable=IsNullable may not be set to 'false' for a Nullable<{0}> type. Consider using '{0}' type or removing the IsNullable property from the XmlElement attribute. throw new InvalidOperationException(Res.GetString(Res.XmlInvalidNotNullable, typeModel.TypeDesc.BaseTypeDesc.FullName, "XmlElement")); element.IsNullable = xmlElement.IsNullableSpecified ? xmlElement.IsNullable : typeModel.TypeDesc.IsOptionalValue; element.Form = rpc ? XmlSchemaForm.Unqualified : xmlElement.Form == XmlSchemaForm.None ? elementFormDefault : xmlElement.Form; CheckNullable(element.IsNullable, targetTypeDesc, element.Mapping); if (!rpc) { CheckForm(element.Form, ns != element.Namespace); element = ReconcileLocalAccessor(element, ns); } if (xmlElement.Order != -1) { if (xmlElement.Order != sequenceId && sequenceId != -1) throw new InvalidOperationException(Res.GetString(Res.XmlSequenceMatch, "Order")); sequenceId = xmlElement.Order; } AddUniqueAccessor(elements, element); elementList.Add(element); } NameTable anys = new NameTable(); for (int i = 0; i < a.XmlAnyElements.Count; i++) { XmlAnyElementAttribute xmlAnyElement = a.XmlAnyElements[i]; Type targetType = typeof(IXmlSerializable).IsAssignableFrom(accessorType) ? accessorType : typeof(XmlNode).IsAssignableFrom(accessorType) ? accessorType : typeof(XmlElement); if (!accessorType.IsAssignableFrom(targetType)) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAnyElement, accessorType.FullName)); string anyName = xmlAnyElement.Name.Length == 0 ? xmlAnyElement.Name : XmlConvert.EncodeLocalName(xmlAnyElement.Name); string anyNs = xmlAnyElement.NamespaceSpecified ? xmlAnyElement.Namespace : null; if (anys[anyName, anyNs] != null) { // ignore duplicate anys continue; } anys[anyName, anyNs] = xmlAnyElement; if (elements[anyName, (anyNs == null ? ns : anyNs)] != null) { throw new InvalidOperationException(Res.GetString(Res.XmlAnyElementDuplicate, accessorName, xmlAnyElement.Name, xmlAnyElement.Namespace == null ? "null" : xmlAnyElement.Namespace)); } ElementAccessor element = new ElementAccessor(); element.Name = anyName; element.Namespace = anyNs == null ? ns : anyNs; element.Any = true; element.AnyNamespaces = anyNs; TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType); TypeModel typeModel = modelScope.GetTypeModel(targetType); if (element.Name.Length > 0) typeModel.TypeDesc.IsMixed = true; element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, String.Empty, null, false, openModel, limiter); element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); element.IsNullable = false; element.Form = elementFormDefault; CheckNullable(element.IsNullable, targetTypeDesc, element.Mapping); if (!rpc) { CheckForm(element.Form, ns != element.Namespace); element = ReconcileLocalAccessor(element, ns); } if (xmlAnyElement.Order != -1) { if (xmlAnyElement.Order != sequenceId && sequenceId != -1) throw new InvalidOperationException(Res.GetString(Res.XmlSequenceMatch, "Order")); sequenceId = xmlAnyElement.Order; } elements.Add(element.Name, element.Namespace, element); elementList.Add(element); } } } accessor.Elements = (ElementAccessor[])elementList.ToArray(typeof(ElementAccessor)); accessor.SequenceId = sequenceId; if (rpc) { if (accessor.TypeDesc.IsArrayLike && accessor.Elements.Length > 0 && !(accessor.Elements[0].Mapping is ArrayMapping)) throw new InvalidOperationException(Res.GetString(Res.XmlRpcLitArrayElement, accessor.Elements[0].Name)); if (accessor.Xmlns != null) throw new InvalidOperationException(Res.GetString(Res.XmlRpcLitXmlns, accessor.Name)); } if (accessor.ChoiceIdentifier != null) { // find the enum value corresponding to each element accessor.ChoiceIdentifier.MemberIds = new string[accessor.Elements.Length]; for (int i = 0; i < accessor.Elements.Length; i++) { bool found = false; ElementAccessor element = accessor.Elements[i]; EnumMapping choiceMapping = (EnumMapping)accessor.ChoiceIdentifier.Mapping; for (int j = 0; j < choiceMapping.Constants.Length; j++) { string xmlName = choiceMapping.Constants[j].XmlName; if (element.Any && element.Name.Length == 0) { string anyNs = element.AnyNamespaces == null ? "##any" : element.AnyNamespaces; if (xmlName.Substring(0, xmlName.Length-1) == anyNs) { accessor.ChoiceIdentifier.MemberIds[i] = choiceMapping.Constants[j].Name; found = true; break; } continue; } int colon = xmlName.LastIndexOf(':'); string choiceNs = colon < 0 ? choiceMapping.Namespace : xmlName.Substring(0, colon); string choiceName = colon < 0 ? xmlName : xmlName.Substring(colon+1); if (element.Name == choiceName) { if ((element.Form == XmlSchemaForm.Unqualified && string.IsNullOrEmpty(choiceNs)) || element.Namespace == choiceNs) { accessor.ChoiceIdentifier.MemberIds[i] = choiceMapping.Constants[j].Name; found = true; break; } } } if (!found) { if (element.Any && element.Name.Length == 0) { // Type {0} is missing enumeration value '##any' for XmlAnyElementAttribute. throw new InvalidOperationException(Res.GetString(Res.XmlChoiceMissingAnyValue, accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName)); } else { string id = element.Namespace != null && element.Namespace.Length > 0 ? element.Namespace + ":" + element.Name : element.Name; // Type {0} is missing value for '{1}'. throw new InvalidOperationException(Res.GetString(Res.XmlChoiceMissingValue, accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName, id, element.Name, element.Namespace)); } } } } arrayNestingLevel = previousNestingLevel; savedArrayItemAttributes = previousArrayItemAttributes; savedArrayNamespace = previousArrayNamespace; }
ElementAccessor ImportElement(TypeModel model, XmlRootAttribute root, string defaultNamespace, RecursionLimiter limiter) { XmlAttributes a = GetAttributes(model.Type, true); if (root == null) root = a.XmlRoot; string ns = root == null ? null : root.Namespace; if (ns == null) ns = defaultNamespace; if (ns == null) ns = this.defaultNs; arrayNestingLevel = -1; savedArrayItemAttributes = null; savedArrayNamespace = null; ElementAccessor element = CreateElementAccessor(ImportTypeMapping(model, ns, ImportContext.Element, string.Empty, a, limiter), ns); if (root != null) { if (root.ElementName.Length > 0) element.Name = XmlConvert.EncodeLocalName(root.ElementName); if (root.IsNullableSpecified && !root.IsNullable && model.TypeDesc.IsOptionalValue) //XmlInvalidNotNullable=IsNullable may not be set to 'false' for a Nullable<{0}> type. Consider using '{0}' type or removing the IsNullable property from the XmlElement attribute. throw new InvalidOperationException(Res.GetString(Res.XmlInvalidNotNullable, model.TypeDesc.BaseTypeDesc.FullName, "XmlRoot")); element.IsNullable = root.IsNullableSpecified ? root.IsNullable : model.TypeDesc.IsNullable || model.TypeDesc.IsOptionalValue; CheckNullable(element.IsNullable, model.TypeDesc, element.Mapping); } else element.IsNullable = model.TypeDesc.IsNullable || model.TypeDesc.IsOptionalValue; element.Form = XmlSchemaForm.Qualified; return (ElementAccessor)ReconcileAccessor(element, this.elements); }
TypeMapping ImportTypeMapping(TypeModel model, string ns, ImportContext context, string dataType, XmlAttributes a, RecursionLimiter limiter) { return ImportTypeMapping(model, ns, context, dataType, a, false, false, limiter); }
TypeMapping ImportTypeMapping(TypeModel model, string ns, ImportContext context, string dataType, XmlAttributes a, bool repeats, bool openModel, RecursionLimiter limiter) { try { if (dataType.Length > 0) { TypeDesc modelTypeDesc = TypeScope.IsOptionalValue(model.Type) ? model.TypeDesc.BaseTypeDesc : model.TypeDesc; if (!modelTypeDesc.IsPrimitive) { throw new InvalidOperationException(Res.GetString(Res.XmlInvalidDataTypeUsage, dataType, "XmlElementAttribute.DataType")); } TypeDesc td = typeScope.GetTypeDesc(dataType, XmlSchema.Namespace); if (td == null) { throw new InvalidOperationException(Res.GetString(Res.XmlInvalidXsdDataType, dataType, "XmlElementAttribute.DataType", new XmlQualifiedName(dataType, XmlSchema.Namespace).ToString())); } if (modelTypeDesc.FullName != td.FullName) { throw new InvalidOperationException(Res.GetString(Res.XmlDataTypeMismatch, dataType, "XmlElementAttribute.DataType", modelTypeDesc.FullName)); } } if (a == null) a = GetAttributes(model.Type, false); if ((a.XmlFlags & ~(XmlAttributeFlags.Type | XmlAttributeFlags.Root)) != 0) throw new InvalidOperationException(Res.GetString(Res.XmlInvalidTypeAttributes, model.Type.FullName)); switch (model.TypeDesc.Kind) { case TypeKind.Enum: return ImportEnumMapping((EnumModel)model, ns, repeats); case TypeKind.Primitive: if (a.XmlFlags != 0) throw InvalidAttributeUseException(model.Type); return ImportPrimitiveMapping((PrimitiveModel)model, context, dataType, repeats); case TypeKind.Array: case TypeKind.Collection: case TypeKind.Enumerable: //if (a.XmlFlags != 0) throw InvalidAttributeUseException(model.Type); if (context != ImportContext.Element) throw UnsupportedException(model.TypeDesc, context); arrayNestingLevel++; ArrayMapping arrayMapping = ImportArrayLikeMapping((ArrayModel)model, ns, limiter); arrayNestingLevel--; return arrayMapping; case TypeKind.Root: case TypeKind.Class: case TypeKind.Struct: if (context != ImportContext.Element) throw UnsupportedException(model.TypeDesc, context); if (model.TypeDesc.IsOptionalValue) { TypeDesc valueTypeDesc = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc : typeScope.GetTypeDesc(dataType, XmlSchema.Namespace); string xsdTypeName = valueTypeDesc.DataType == null ? valueTypeDesc.Name : valueTypeDesc.DataType.Name; TypeMapping baseMapping = GetTypeMapping(xsdTypeName, ns, valueTypeDesc, types, null); if (baseMapping == null) baseMapping = ImportTypeMapping(modelScope.GetTypeModel(model.TypeDesc.BaseTypeDesc.Type), ns, context, dataType, null, repeats, openModel, limiter); return CreateNullableMapping(baseMapping, model.TypeDesc.Type); } else { return ImportStructLikeMapping((StructModel)model, ns, openModel, a, limiter); } default: if (model.TypeDesc.Kind == TypeKind.Serializable) { // We allow XmlRoot attribute on IXmlSerializable, but not others if ((a.XmlFlags & ~XmlAttributeFlags.Root) != 0) { throw new InvalidOperationException(Res.GetString(Res.XmlSerializableAttributes, model.TypeDesc.FullName, typeof(XmlSchemaProviderAttribute).Name)); } } else { if (a.XmlFlags != 0) throw InvalidAttributeUseException(model.Type); } if (model.TypeDesc.IsSpecial) return ImportSpecialMapping(model.Type, model.TypeDesc, ns, context, limiter); throw UnsupportedException(model.TypeDesc, context); } } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } throw CreateTypeReflectionException(model.TypeDesc.FullName, e); } }
private TypeMapping ImportTypeMapping(TypeModel model, string dataType, RecursionLimiter limiter) { if (dataType.Length > 0) { if (!model.TypeDesc.IsPrimitive) { throw new InvalidOperationException(SR.Format(SR.XmlInvalidDataTypeUsage, dataType, "SoapElementAttribute.DataType")); } TypeDesc td = _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace); if (td == null) { throw new InvalidOperationException(SR.Format(SR.XmlInvalidXsdDataType, dataType, "SoapElementAttribute.DataType", new XmlQualifiedName(dataType, XmlSchema.Namespace).ToString())); } if (model.TypeDesc.FullName != td.FullName) { throw new InvalidOperationException(SR.Format(SR.XmlDataTypeMismatch, dataType, "SoapElementAttribute.DataType", model.TypeDesc.FullName)); } } SoapAttributes a = GetAttributes(model.Type); if ((a.GetSoapFlags() & ~SoapAttributeFlags.Type) != 0) { throw new InvalidOperationException(SR.Format(SR.XmlInvalidTypeAttributes, model.Type.FullName)); } switch (model.TypeDesc.Kind) { case TypeKind.Enum: return(ImportEnumMapping((EnumModel)model)); case TypeKind.Primitive: return(ImportPrimitiveMapping((PrimitiveModel)model, dataType)); case TypeKind.Array: case TypeKind.Collection: case TypeKind.Enumerable: return(ImportArrayLikeMapping((ArrayModel)model, limiter)); case TypeKind.Root: case TypeKind.Class: case TypeKind.Struct: if (model.TypeDesc.IsOptionalValue) { TypeDesc baseTypeDesc = model.TypeDesc.BaseTypeDesc; SoapAttributes baseAttributes = GetAttributes(baseTypeDesc.Type); string typeNs = _defaultNs; if (baseAttributes.SoapType != null && baseAttributes.SoapType.Namespace != null) { typeNs = baseAttributes.SoapType.Namespace; } TypeDesc valueTypeDesc = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc : _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace); string xsdTypeName = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc.Name : dataType; TypeMapping baseMapping = GetTypeMapping(xsdTypeName, typeNs, valueTypeDesc); if (baseMapping == null) { baseMapping = ImportTypeMapping(_modelScope.GetTypeModel(baseTypeDesc.Type), dataType, limiter); } return(CreateNullableMapping(baseMapping, model.TypeDesc.Type)); } else { return(ImportStructLikeMapping((StructModel)model, limiter)); } default: throw new NotSupportedException(SR.Format(SR.XmlUnsupportedSoapTypeKind, model.TypeDesc.FullName)); } }
SpecialMapping ImportSpecialMapping(Type type, TypeDesc typeDesc, string ns, ImportContext context, RecursionLimiter limiter) { if (specials == null) specials = new Hashtable(); SpecialMapping mapping = (SpecialMapping)specials[type]; if (mapping != null) { CheckContext(mapping.TypeDesc, context); return mapping; } if (typeDesc.Kind == TypeKind.Serializable) { // SerializableMapping serializableMapping = null; // get the schema method info object[] attrs = type.GetCustomAttributes(typeof(XmlSchemaProviderAttribute), false); if (attrs.Length > 0) { // new IXmlSerializable XmlSchemaProviderAttribute provider = (XmlSchemaProviderAttribute)attrs[0]; MethodInfo method = GetMethodFromSchemaProvider(provider, type); serializableMapping = new SerializableMapping(method, provider.IsAny, ns); XmlQualifiedName qname = serializableMapping.XsiType; if (qname != null && !qname.IsEmpty) { if (serializables == null) serializables = new NameTable(); SerializableMapping existingMapping = (SerializableMapping)serializables[qname]; if (existingMapping != null) { if (existingMapping.Type == null) { serializableMapping = existingMapping; } else if (existingMapping.Type != type) { SerializableMapping next = existingMapping.Next; existingMapping.Next = serializableMapping; serializableMapping.Next = next; } } else { XmlSchemaType xsdType = serializableMapping.XsdType; if (xsdType != null) SetBase(serializableMapping, xsdType.DerivedFrom); serializables[qname] = serializableMapping; } serializableMapping.TypeName = qname.Name; serializableMapping.Namespace = qname.Namespace; } serializableMapping.TypeDesc = typeDesc; serializableMapping.Type = type; IncludeTypes(type); } else { // old IXmlSerializable serializableMapping = new SerializableMapping(); serializableMapping.TypeDesc = typeDesc; serializableMapping.Type = type; } mapping = serializableMapping; } else { mapping = new SpecialMapping(); mapping.TypeDesc = typeDesc; } CheckContext(typeDesc, context); specials.Add(type, mapping); typeScope.AddTypeMapping(mapping); return mapping; }
private bool InitializeStructMembers(StructMapping mapping, StructModel model, RecursionLimiter limiter) { if (mapping.IsFullyInitialized) { return(true); } if (model.TypeDesc.BaseTypeDesc != null) { StructMapping baseMapping = ImportStructLikeMapping((StructModel)_modelScope.GetTypeModel(model.Type.BaseType, false), limiter); // check to see if the import of the baseMapping was deferred int baseIndex = limiter.DeferredWorkItems.IndexOf(mapping.BaseMapping); if (baseIndex < 0) { mapping.BaseMapping = baseMapping; } else { // the import of the baseMapping was deferred, make sure that the derived mappings is deferred as well if (!limiter.DeferredWorkItems.Contains(mapping)) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping)); } // make sure that baseMapping get processed before the derived int top = limiter.DeferredWorkItems.Count - 1; if (baseIndex < top) { ImportStructWorkItem baseMappingWorkItem = limiter.DeferredWorkItems[baseIndex]; limiter.DeferredWorkItems[baseIndex] = limiter.DeferredWorkItems[top]; limiter.DeferredWorkItems[top] = baseMappingWorkItem; } return(false); } } ArrayList members = new ArrayList(); foreach (MemberInfo memberInfo in model.GetMemberInfos()) { if (!(memberInfo is FieldInfo) && !(memberInfo is PropertyInfo)) { continue; } SoapAttributes memberAttrs = GetAttributes(memberInfo); if (memberAttrs.SoapIgnore) { continue; } FieldModel fieldModel = model.GetFieldModel(memberInfo); if (fieldModel == null) { continue; } MemberMapping member = ImportFieldMapping(fieldModel, memberAttrs, mapping.Namespace, limiter); if (member == null) { continue; } if (!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum && !member.TypeDesc.IsOptionalValue) { if (model.TypeDesc.IsValueType) { throw new NotSupportedException(SR.Format(SR.XmlRpcRefsInValueType, model.TypeDesc.FullName)); } if (member.TypeDesc.IsValueType) { throw new NotSupportedException(SR.Format(SR.XmlRpcNestedValueType, member.TypeDesc.FullName)); } } if (mapping.BaseMapping != null) { if (mapping.BaseMapping.Declares(member, mapping.TypeName)) { continue; } } members.Add(member); } mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping)); if (mapping.BaseMapping == null) { mapping.BaseMapping = GetRootMapping(); } IncludeTypes(model.Type, limiter); return(true); }
private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, SoapAttributes a, string ns, XmlSchemaForm form, RecursionLimiter limiter) { Type fieldType = model.FieldType; string name = model.Name; accessor.TypeDesc = this.typeScope.GetTypeDesc(fieldType); if (accessor.TypeDesc.IsVoid) { throw new InvalidOperationException(Res.GetString("XmlInvalidVoid")); } SoapAttributeFlags soapFlags = a.SoapFlags; if ((soapFlags & SoapAttributeFlags.Attribute) == SoapAttributeFlags.Attribute) { if (!accessor.TypeDesc.IsPrimitive && !accessor.TypeDesc.IsEnum) { throw new InvalidOperationException(Res.GetString("XmlIllegalSoapAttribute", new object[] { name, accessor.TypeDesc.FullName })); } if ((soapFlags & SoapAttributeFlags.Attribute) != soapFlags) { throw new InvalidOperationException(Res.GetString("XmlInvalidElementAttribute")); } AttributeAccessor accessor2 = new AttributeAccessor { Name = Accessor.EscapeQName(((a.SoapAttribute == null) || (a.SoapAttribute.AttributeName.Length == 0)) ? name : a.SoapAttribute.AttributeName), Namespace = ((a.SoapAttribute == null) || (a.SoapAttribute.Namespace == null)) ? ns : a.SoapAttribute.Namespace, Form = XmlSchemaForm.Qualified, Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(fieldType), (a.SoapAttribute == null) ? string.Empty : a.SoapAttribute.DataType, limiter), Default = this.GetDefaultValue(model.FieldTypeDesc, a) }; accessor.Attribute = accessor2; accessor.Elements = new ElementAccessor[0]; } else { if ((soapFlags & SoapAttributeFlags.Element) != soapFlags) { throw new InvalidOperationException(Res.GetString("XmlInvalidElementAttribute")); } ElementAccessor accessor3 = new ElementAccessor { IsSoap = true, Name = XmlConvert.EncodeLocalName(((a.SoapElement == null) || (a.SoapElement.ElementName.Length == 0)) ? name : a.SoapElement.ElementName), Namespace = ns, Form = form, Mapping = this.ImportTypeMapping(this.modelScope.GetTypeModel(fieldType), (a.SoapElement == null) ? string.Empty : a.SoapElement.DataType, limiter) }; if (a.SoapElement != null) { accessor3.IsNullable = a.SoapElement.IsNullable; } accessor.Elements = new ElementAccessor[] { accessor3 }; } }
private MembersMapping ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, string ns, bool hasWrapperElement, bool writeAccessors, bool validateWrapperElement, RecursionLimiter limiter) { MembersMapping members = new MembersMapping(); members.TypeDesc = _typeScope.GetTypeDesc(typeof(object[])); MemberMapping[] mappings = new MemberMapping[xmlReflectionMembers.Length]; for (int i = 0; i < mappings.Length; i++) { try { XmlReflectionMember member = xmlReflectionMembers[i]; MemberMapping mapping = ImportMemberMapping(member, ns, xmlReflectionMembers, hasWrapperElement ? XmlSchemaForm.Unqualified : XmlSchemaForm.Qualified, limiter); if (member.IsReturnValue && writeAccessors) { // no special treatment for return values with doc/enc if (i > 0) { throw new InvalidOperationException(SR.XmlInvalidReturnPosition); } mapping.IsReturnValue = true; } mappings[i] = mapping; } catch (Exception e) { if (e is OutOfMemoryException) { throw; } throw ReflectionException(xmlReflectionMembers[i].MemberName, e); } } members.Members = mappings; members.HasWrapperElement = hasWrapperElement; if (hasWrapperElement) { members.ValidateRpcWrapperElement = validateWrapperElement; } members.WriteAccessors = writeAccessors; members.IsSoap = true; if (hasWrapperElement && !writeAccessors) { members.Namespace = ns; } return(members); }
bool InitializeStructMembers(StructMapping mapping, StructModel model, bool openModel, string typeName, RecursionLimiter limiter) { if (mapping.IsFullyInitialized) return true; if (model.TypeDesc.BaseTypeDesc != null) { TypeModel baseModel = modelScope.GetTypeModel(model.Type.BaseType, false); if (!(baseModel is StructModel)) { //XmlUnsupportedInheritance=Using '{0}' as a base type for a class is not supported by XmlSerializer. throw new NotSupportedException(Res.GetString(Res.XmlUnsupportedInheritance, model.Type.BaseType.FullName)); } StructMapping baseMapping = ImportStructLikeMapping((StructModel)baseModel, mapping.Namespace, openModel, null, limiter); // check to see if the import of the baseMapping was deffered int baseIndex = limiter.DeferredWorkItems.IndexOf(baseMapping); if (baseIndex < 0) { mapping.BaseMapping = baseMapping; ICollection values = mapping.BaseMapping.LocalAttributes.Values; foreach (AttributeAccessor attribute in values) { AddUniqueAccessor(mapping.LocalAttributes, attribute); } if (!mapping.BaseMapping.HasExplicitSequence()) { values = mapping.BaseMapping.LocalElements.Values; foreach (ElementAccessor e in values) { AddUniqueAccessor(mapping.LocalElements, e); } } } else { // the import of the baseMapping was deffered, make sure that the derived mappings is deffered as well if (!limiter.DeferredWorkItems.Contains(mapping)) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping)); } // make sure that baseMapping get processed before the derived int top = limiter.DeferredWorkItems.Count - 1; if (baseIndex < top) { ImportStructWorkItem baseMappingWorkItem = limiter.DeferredWorkItems[baseIndex]; limiter.DeferredWorkItems[baseIndex] = limiter.DeferredWorkItems[top]; limiter.DeferredWorkItems[top] = baseMappingWorkItem; } return false; } } ArrayList members = new ArrayList(); TextAccessor textAccesor = null; bool hasElements = false; bool isSequence = false; foreach (MemberInfo memberInfo in model.GetMemberInfos()) { if ((memberInfo.MemberType & (MemberTypes.Field | MemberTypes.Property)) == 0) continue; XmlAttributes memberAttrs = GetAttributes(memberInfo); if (memberAttrs.XmlIgnore) continue; FieldModel fieldModel = model.GetFieldModel(memberInfo); if (fieldModel == null) continue; try { MemberMapping member = ImportFieldMapping(model, fieldModel, memberAttrs, mapping.Namespace, limiter); if (member == null) continue; if (mapping.BaseMapping != null) { if (mapping.BaseMapping.Declares(member, mapping.TypeName)) continue; } isSequence |= member.IsSequence; // add All memeber accessors to the scope accessors AddUniqueAccessor(member, mapping.LocalElements, mapping.LocalAttributes, isSequence); if (member.Text != null) { if (!member.Text.Mapping.TypeDesc.CanBeTextValue && member.Text.Mapping.IsList) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalTypedTextAttribute, typeName, member.Text.Name, member.Text.Mapping.TypeDesc.FullName)); if (textAccesor != null) { throw new InvalidOperationException(Res.GetString(Res.XmlIllegalMultipleText, model.Type.FullName)); } textAccesor = member.Text; } if (member.Xmlns != null) { if (mapping.XmlnsMember != null) throw new InvalidOperationException(Res.GetString(Res.XmlMultipleXmlns, model.Type.FullName)); mapping.XmlnsMember = member; } if (member.Elements != null && member.Elements.Length != 0) { hasElements = true; } members.Add(member); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } throw CreateMemberReflectionException(fieldModel, e); } } mapping.SetContentModel(textAccesor, hasElements); if (isSequence) { Hashtable ids = new Hashtable(); for (int i = 0; i < members.Count; i++) { MemberMapping member = (MemberMapping)members[i]; if (!member.IsParticle) continue; if (member.IsSequence) { if (ids[member.SequenceId] != null) { throw new InvalidOperationException(Res.GetString(Res.XmlSequenceUnique, member.SequenceId.ToString(CultureInfo.InvariantCulture), "Order", member.Name)); } ids[member.SequenceId] = member; } else { throw new InvalidOperationException(Res.GetString(Res.XmlSequenceInconsistent, "Order", member.Name)); } } members.Sort(new MemberMappingComparer()); } mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping)); if (mapping.BaseMapping == null) mapping.BaseMapping = GetRootMapping(); if (mapping.XmlnsMember != null && mapping.BaseMapping.HasXmlnsMember) throw new InvalidOperationException(Res.GetString(Res.XmlMultipleXmlns, model.Type.FullName)); IncludeTypes(model.Type, limiter); typeScope.AddTypeMapping(mapping); if (openModel) mapping.IsOpenModel = true; return true; }
private MemberMapping ImportFieldMapping(FieldModel model, SoapAttributes a, string ns, RecursionLimiter limiter) { if (a.SoapIgnore) { return(null); } MemberMapping member = new MemberMapping(); member.IsSoap = true; member.Name = model.Name; member.CheckShouldPersist = model.CheckShouldPersist; member.CheckSpecified = model.CheckSpecified; member.MemberInfo = model.MemberInfo; member.CheckSpecifiedMemberInfo = model.CheckSpecifiedMemberInfo; member.CheckShouldPersistMethodInfo = model.CheckShouldPersistMethodInfo; member.ReadOnly = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor; ImportAccessorMapping(member, model, a, ns, XmlSchemaForm.Unqualified, limiter); return(member); }
ArrayMapping ImportArrayLikeMapping(ArrayModel model, string ns, RecursionLimiter limiter) { ArrayMapping mapping = new ArrayMapping(); mapping.TypeDesc = model.TypeDesc; if (savedArrayItemAttributes == null) savedArrayItemAttributes = new XmlArrayItemAttributes(); if (CountAtLevel(savedArrayItemAttributes, arrayNestingLevel) == 0) savedArrayItemAttributes.Add(CreateArrayItemAttribute(typeScope.GetTypeDesc(model.Element.Type), arrayNestingLevel)); CreateArrayElementsFromAttributes(mapping, savedArrayItemAttributes, model.Element.Type, savedArrayNamespace == null ? ns : savedArrayNamespace, limiter); SetArrayMappingType(mapping, ns, model.Type); // reconcile accessors now that we have the ArrayMapping namespace for (int i = 0; i < mapping.Elements.Length; i++) { mapping.Elements[i] = ReconcileLocalAccessor(mapping.Elements[i], mapping.Namespace); } IncludeTypes(model.Type); // in the case of an ArrayMapping we can have more that one mapping correspond to a type // examples of that are ArrayList and object[] both will map tp ArrayOfur-type // so we create a link list for all mappings of the same XSD type ArrayMapping existingMapping = (ArrayMapping)types[mapping.TypeName, mapping.Namespace]; if (existingMapping != null) { ArrayMapping first = existingMapping; while (existingMapping != null) { if (existingMapping.TypeDesc == model.TypeDesc) return existingMapping; existingMapping = existingMapping.Next; } mapping.Next = first; if (!mapping.IsAnonymousType) types[mapping.TypeName, mapping.Namespace] = mapping; else anonymous[model.Type] = mapping; return mapping; } typeScope.AddTypeMapping(mapping); if (!mapping.IsAnonymousType) types.Add(mapping.TypeName, mapping.Namespace, mapping); else anonymous[model.Type] = mapping; return mapping; }
StructMapping ImportStructLikeMapping(StructModel model, string ns, bool openModel, XmlAttributes a, RecursionLimiter limiter) { if (model.TypeDesc.Kind == TypeKind.Root) return GetRootMapping(); if (a == null) a = GetAttributes(model.Type, false); string typeNs = ns; if (a.XmlType != null && a.XmlType.Namespace != null) typeNs = a.XmlType.Namespace; else if (a.XmlRoot != null && a.XmlRoot.Namespace != null) typeNs = a.XmlRoot.Namespace; string typeName = IsAnonymousType(a, ns) ? null : XsdTypeName(model.Type, a, model.TypeDesc.Name); typeName = XmlConvert.EncodeLocalName(typeName); StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc, types, model.Type); if (mapping == null) { mapping = new StructMapping(); mapping.TypeDesc = model.TypeDesc; mapping.Namespace = typeNs; mapping.TypeName = typeName; if (!mapping.IsAnonymousType) types.Add(typeName, typeNs, mapping); else anonymous[model.Type] = mapping; if (a.XmlType != null) { mapping.IncludeInSchema = a.XmlType.IncludeInSchema; } if (limiter.IsExceededLimit) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping)); return mapping; } limiter.Depth++; InitializeStructMembers(mapping, model, openModel, typeName, limiter); while (limiter.DeferredWorkItems.Count > 0) { int index = limiter.DeferredWorkItems.Count - 1; ImportStructWorkItem item = limiter.DeferredWorkItems[index]; if (InitializeStructMembers(item.Mapping, item.Model, openModel, typeName, limiter)) { // // if InitializeStructMembers returns true, then there were *no* chages to the DeferredWorkItems // #if DEBUG // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe if (index != limiter.DeferredWorkItems.Count - 1) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "DeferredWorkItems.Count have changed")); if (item != limiter.DeferredWorkItems[index]) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "DeferredWorkItems.Top have changed")); #endif // Remove the last work item limiter.DeferredWorkItems.RemoveAt(index); } } limiter.Depth--; } return mapping; }
private MemberMapping ImportMemberMapping(XmlReflectionMember xmlReflectionMember, string ns, XmlReflectionMember[] xmlReflectionMembers, XmlSchemaForm form, RecursionLimiter limiter) { SoapAttributes soapAttributes = xmlReflectionMember.SoapAttributes; if (soapAttributes.SoapIgnore) { return(null); } MemberMapping accessor = new MemberMapping { IsSoap = true, Name = xmlReflectionMember.MemberName }; bool checkSpecified = XmlReflectionImporter.FindSpecifiedMember(xmlReflectionMember.MemberName, xmlReflectionMembers) != null; FieldModel model = new FieldModel(xmlReflectionMember.MemberName, xmlReflectionMember.MemberType, this.typeScope.GetTypeDesc(xmlReflectionMember.MemberType), checkSpecified, false); accessor.CheckShouldPersist = model.CheckShouldPersist; accessor.CheckSpecified = model.CheckSpecified; accessor.ReadOnly = model.ReadOnly; this.ImportAccessorMapping(accessor, model, soapAttributes, ns, form, limiter); if (xmlReflectionMember.OverrideIsNullable) { accessor.Elements[0].IsNullable = false; } return(accessor); }