Exception CreateMemberReflectionException(FieldModel model, Exception e) { return new InvalidOperationException(Res.GetString(model.IsProperty ? Res.XmlPropertyReflectionError : Res.XmlFieldReflectionError, model.Name), e); }
MemberMapping ImportMemberMapping(XmlReflectionMember xmlReflectionMember, string ns, XmlReflectionMember[] xmlReflectionMembers, XmlSchemaForm form) { 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); if (xmlReflectionMember.OverrideIsNullable) member.Elements[0].IsNullable = false; return member; }
MemberMapping ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, string ns) { MemberMapping member = new MemberMapping(); member.Name = model.Name; 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, parent, model.FieldTypeDesc.IsArrayLike, model.Name); } ImportAccessorMapping(member, model, a, ns, choiceIdentifierType, false, false); return member; }
void ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, string ns, Type choiceIdentifierType, bool rpc, bool openModel) { 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.Mapping = ImportTypeMapping(modelScope.GetTypeModel(choiceIdentifierType), ns, ImportContext.Element, String.Empty, null); 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); 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); 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); 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) 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); 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); 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); 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); 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); 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) 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); 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) 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); 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; }
void ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, string ns, XmlSchemaForm form, Type choiceIdentifierType) { int previousNestingLevel = arrayNestingLevel; XmlArrayItemAttributes previousArrayItemAttributes = savedArrayItemAttributes; string previousArrayNamespace = savedArrayNamespace; arrayNestingLevel = 0; savedArrayItemAttributes = null; savedArrayNamespace = null; Type accessorType = model.FieldType; string accessorName = model.Name; NameTable elements = new NameTable(); accessor.TypeDesc = typeScope.GetTypeDesc(accessorType); XmlAttributeFlags flags = a.XmlFlags; accessor.Ignore = a.XmlIgnore; 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.Mapping = ImportTypeMapping(modelScope.GetTypeModel(choiceIdentifierType), ns, ImportContext.Element, String.Empty); } if (accessor.TypeDesc.IsArrayLike) { Type arrayElementType = TypeScope.GetArrayElementType(accessorType); 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) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttrOrText, accessorName)); 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.EscapeName(a.XmlAttribute.AttributeName.Length == 0 ? accessorName : a.XmlAttribute.AttributeName, true); attribute.Namespace = a.XmlAttribute.Namespace == null ? ns : a.XmlAttribute.Namespace; attribute.Form = a.XmlAttribute.Form; // == XmlSchemaForm.None ? 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, XmlSchemaForm.Qualified, isList); attribute.IsList = isList; attribute.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); attribute.Any = (a.XmlAnyAttribute != null); 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, XmlSchemaForm.Qualified, true); 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 = xmlElement.Namespace == null ? ns : xmlElement.Namespace; element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, xmlElement.DataType); if (a.XmlElements.Count == 1) { element.Name = Accessor.EscapeName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName, false); } else { element.Name = Accessor.EscapeName(xmlElement.ElementName.Length == 0 ? element.Mapping.TypeName : xmlElement.ElementName, false); } element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); element.IsNullable = xmlElement.IsNullable; element.Form = xmlElement.Form == XmlSchemaForm.None ? form : xmlElement.Form; CheckForm(element.Form, ns != element.Namespace); CheckNullable(element.IsNullable, targetTypeDesc); element = ReconcileLocalAccessor(element, ns); AddUniqueAccessor(elements, element); } for (int i = 0; i < a.XmlAnyElements.Count; i++) { XmlAnyElementAttribute xmlAnyElement = a.XmlAnyElements[i]; Type targetType = typeof(XmlNode).IsAssignableFrom(arrayElementType) ? arrayElementType : typeof(XmlElement); ElementAccessor element = new ElementAccessor(); element.Name = Accessor.EscapeName(xmlAnyElement.Name, false); element.Namespace = xmlAnyElement.Namespace == null ? ns : xmlAnyElement.Namespace; element.Any = true; TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType); TypeModel typeModel = modelScope.GetTypeModel(targetType); if (element.Name != String.Empty) typeModel.TypeDesc.IsMixed = true; else if (xmlAnyElement.Namespace != null) throw new InvalidOperationException(Res.GetString(Res.XmlAnyElementNamespace, accessorName, xmlAnyElement.Namespace)); element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, String.Empty); element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); element.IsNullable = false; element.Form = form; CheckForm(element.Form, ns != element.Namespace); CheckNullable(element.IsNullable, targetTypeDesc); element = ReconcileLocalAccessor(element, ns); elements.Add(element.Name, element.Namespace, element); } } 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 = Accessor.EscapeName(a.XmlArray.ElementName.Length == 0 ? accessorName : a.XmlArray.ElementName, false); arrayElement.Namespace = a.XmlArray.Namespace == null ? ns : a.XmlArray.Namespace; savedArrayItemAttributes = a.XmlArrayItems; savedArrayNamespace = arrayElement.Namespace; ArrayMapping arrayMapping = ImportArrayLikeMapping(modelScope.GetArrayModel(accessorType), ns, form); arrayElement.Mapping = arrayMapping; arrayElement.IsNullable = a.XmlArray.IsNullable; arrayElement.Form = a.XmlArray.Form == XmlSchemaForm.None ? form : a.XmlArray.Form; CheckForm(arrayElement.Form, ns != arrayElement.Namespace); CheckNullable(arrayElement.IsNullable, accessor.TypeDesc); savedArrayItemAttributes = null; savedArrayNamespace = null; arrayElement = ReconcileLocalAccessor(arrayElement, ns); AddUniqueAccessor(elements, 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)); 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.EscapeName(a.XmlAttribute.AttributeName.Length == 0 ? accessorName : a.XmlAttribute.AttributeName, true); attribute.Namespace = a.XmlAttribute.Namespace == null ? ns : a.XmlAttribute.Namespace; attribute.Form = a.XmlAttribute.Form; // == XmlSchemaForm.None ? 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); attribute.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); attribute.Any = a.XmlAnyAttribute != null; 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); 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 = Accessor.EscapeName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName, false); element.Namespace = xmlElement.Namespace == null ? ns : xmlElement.Namespace; element.Mapping = ImportTypeMapping(modelScope.GetTypeModel(accessorType), element.Namespace, ImportContext.Element, xmlElement.DataType); element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); element.IsNullable = xmlElement.IsNullable; element.Form = xmlElement.Form == XmlSchemaForm.None ? form : xmlElement.Form; CheckForm(element.Form, ns != element.Namespace); CheckNullable(element.IsNullable, accessor.TypeDesc); element = ReconcileLocalAccessor(element, ns); AddUniqueAccessor(elements, 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) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalAttrOrText, accessorName)); 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 = xmlElement.Namespace == null ? ns : xmlElement.Namespace; element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, xmlElement.DataType); if (a.XmlElements.Count == 1) { element.Name = Accessor.EscapeName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName, false); } else { element.Name = Accessor.EscapeName(xmlElement.ElementName.Length == 0 ? element.Mapping.TypeName : xmlElement.ElementName, false); } element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); element.IsNullable = xmlElement.IsNullable; element.Form = xmlElement.Form == XmlSchemaForm.None ? form : xmlElement.Form; CheckForm(element.Form, ns != element.Namespace); CheckNullable(element.IsNullable, targetTypeDesc); element = ReconcileLocalAccessor(element, ns); AddUniqueAccessor(elements, element); } for (int i = 0; i < a.XmlAnyElements.Count; i++) { XmlAnyElementAttribute xmlAnyElement = a.XmlAnyElements[i]; Type targetType = typeof(XmlNode).IsAssignableFrom(accessorType) ? accessorType : typeof(XmlElement); ElementAccessor element = new ElementAccessor(); element.Name = Accessor.EscapeName(xmlAnyElement.Name, false); element.Namespace = xmlAnyElement.Namespace == null ? ns : xmlAnyElement.Namespace; element.Any = true; TypeDesc targetTypeDesc = typeScope.GetTypeDesc(targetType); TypeModel typeModel = modelScope.GetTypeModel(targetType); if (element.Name != String.Empty) typeModel.TypeDesc.IsMixed = true; else if (xmlAnyElement.Namespace != null) throw new InvalidOperationException(Res.GetString(Res.XmlAnyElementNamespace, accessorName, xmlAnyElement.Namespace)); element.Mapping = ImportTypeMapping(typeModel, element.Namespace, ImportContext.Element, String.Empty); element.Default = GetDefaultValue(model.FieldTypeDesc, model.FieldType, a); element.IsNullable = false; element.Form = form; CheckForm(element.Form, ns != element.Namespace); CheckNullable(element.IsNullable, targetTypeDesc); element = ReconcileLocalAccessor(element, ns); elements.Add(element.Name, element.Namespace, element); } } } accessor.Elements = (ElementAccessor[])elements.ToArray(typeof(ElementAccessor)); 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; int colon = xmlName.LastIndexOf(':'); string choiceNs = colon < 0 ? element.Namespace : xmlName.Substring(0, colon); string choiceName = colon < 0 ? xmlName : xmlName.Substring(colon+1); if (element.Name == choiceName && element.Namespace == choiceNs) { accessor.ChoiceIdentifier.MemberIds[i] = choiceMapping.Constants[j].Name; found = true; break; } } if (!found) { // Type {0} is missing value for '{1}'. throw new InvalidOperationException(Res.GetString(Res.XmlChoiceMissingValue, accessor.ChoiceIdentifier.Mapping.TypeDesc.FullName, element.Name)); } } } arrayNestingLevel = previousNestingLevel; savedArrayItemAttributes = previousArrayItemAttributes; savedArrayNamespace = previousArrayNamespace; }
MemberMapping ImportMemberMapping(XmlReflectionMember xmlReflectionMember, string ns, XmlReflectionMember[] xmlReflectionMembers, bool rpc, bool openModel) { 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); if (xmlReflectionMember.OverrideIsNullable && member.Elements.Length > 0) member.Elements[0].IsNullable = false; return member; }
private Exception CreateMemberReflectionException(FieldModel model, Exception e) { return new InvalidOperationException(SR.Format(model.IsProperty ? SR.XmlPropertyReflectionError : SR.XmlFieldReflectionError, model.Name), e); }
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 Exception CreateMemberReflectionException(FieldModel model, Exception e) { return new InvalidOperationException(Res.GetString(model.IsProperty ? "XmlPropertyReflectionError" : "XmlFieldReflectionError", new object[] { model.Name }), e); }
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 MemberMapping ImportMemberMapping(XmlReflectionMember xmlReflectionMember, string ns, XmlReflectionMember[] xmlReflectionMembers, bool rpc, bool openModel, RecursionLimiter limiter) { XmlSchemaForm form = rpc ? XmlSchemaForm.Unqualified : XmlSchemaForm.Qualified; XmlAttributes xmlAttributes = xmlReflectionMember.XmlAttributes; TypeDesc typeDesc = this.typeScope.GetTypeDesc(xmlReflectionMember.MemberType); if (xmlAttributes.XmlFlags == ((XmlAttributeFlags) 0)) { if (typeDesc.IsArrayLike) { XmlArrayAttribute attribute = CreateArrayAttribute(typeDesc); attribute.ElementName = xmlReflectionMember.MemberName; attribute.Namespace = rpc ? null : ns; attribute.Form = form; xmlAttributes.XmlArray = attribute; } else { XmlElementAttribute attribute2 = CreateElementAttribute(typeDesc); if (typeDesc.IsStructLike) { XmlAttributes attributes2 = new XmlAttributes(xmlReflectionMember.MemberType); if (attributes2.XmlRoot != null) { if (attributes2.XmlRoot.ElementName.Length > 0) { attribute2.ElementName = attributes2.XmlRoot.ElementName; } if (rpc) { attribute2.Namespace = null; if (attributes2.XmlRoot.IsNullableSpecified) { attribute2.IsNullable = attributes2.XmlRoot.IsNullable; } } else { attribute2.Namespace = attributes2.XmlRoot.Namespace; attribute2.IsNullable = attributes2.XmlRoot.IsNullable; } } } if (attribute2.ElementName.Length == 0) { attribute2.ElementName = xmlReflectionMember.MemberName; } if ((attribute2.Namespace == null) && !rpc) { attribute2.Namespace = ns; } attribute2.Form = form; xmlAttributes.XmlElements.Add(attribute2); } } else if (xmlAttributes.XmlRoot != null) { CheckNullable(xmlAttributes.XmlRoot.IsNullable, typeDesc, null); } MemberMapping accessor = new MemberMapping { Name = xmlReflectionMember.MemberName }; bool checkSpecified = 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; Type choiceIdentifierType = null; if (xmlAttributes.XmlChoiceIdentifier != null) { choiceIdentifierType = this.GetChoiceIdentifierType(xmlAttributes.XmlChoiceIdentifier, xmlReflectionMembers, typeDesc.IsArrayLike, model.Name); } this.ImportAccessorMapping(accessor, model, xmlAttributes, ns, choiceIdentifierType, rpc, openModel, limiter); if (xmlReflectionMember.OverrideIsNullable && (accessor.Elements.Length > 0)) { accessor.Elements[0].IsNullable = false; } return accessor; }
private MemberMapping ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, string ns, RecursionLimiter limiter) { MemberMapping accessor = new MemberMapping { Name = model.Name, CheckShouldPersist = model.CheckShouldPersist, CheckSpecified = model.CheckSpecified, ReadOnly = model.ReadOnly }; Type choiceIdentifierType = null; if (a.XmlChoiceIdentifier != null) { choiceIdentifierType = this.GetChoiceIdentifierType(a.XmlChoiceIdentifier, parent, model.FieldTypeDesc.IsArrayLike, model.Name); } this.ImportAccessorMapping(accessor, model, a, ns, choiceIdentifierType, false, false, limiter); return accessor; }
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); }
MemberMapping ImportFieldMapping(FieldModel model, SoapAttributes a, string ns) { 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.ReadOnly = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor; ImportAccessorMapping(member, model, a, ns, XmlSchemaForm.Unqualified); return member; }
void ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, string ns) { ImportAccessorMapping(accessor, model, a, ns, XmlSchemaForm.None, null); }
void ImportAccessorMapping(MemberMapping accessor, FieldModel model, SoapAttributes a, string ns, XmlSchemaForm form) { Type accessorType = model.FieldType; string accessorName = model.Name; accessor.TypeDesc = typeScope.GetTypeDesc(accessorType); if (accessor.TypeDesc.IsVoid) { throw new InvalidOperationException(Res.GetString(Res.XmlInvalidVoid)); } SoapAttributeFlags flags = a.SoapFlags; if ((flags & SoapAttributeFlags.Attribute) == SoapAttributeFlags.Attribute) { if (!accessor.TypeDesc.IsPrimitive && !accessor.TypeDesc.IsEnum) throw new InvalidOperationException(Res.GetString(Res.XmlIllegalSoapAttribute, accessorName, accessor.TypeDesc.FullName)); if ((flags & SoapAttributeFlags.Attribute) != flags) throw new InvalidOperationException(Res.GetString(Res.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)); attribute.Default = GetDefaultValue(model.FieldTypeDesc, a); accessor.Attribute = attribute; accessor.Elements = new ElementAccessor[0]; } else { if ((flags & SoapAttributeFlags.Element) != flags) throw new InvalidOperationException(Res.GetString(Res.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)); if (a.SoapElement != null) element.IsNullable = a.SoapElement.IsNullable; accessor.Elements = new ElementAccessor[] { element }; } }
MemberMapping ImportMemberMapping(XmlReflectionMember xmlReflectionMember, string ns, XmlSchemaForm form) { SoapAttributes a = xmlReflectionMember.SoapAttributes; if (a.SoapIgnore) return null; MemberMapping member = new MemberMapping(); member.IsSoap = true; member.Name = xmlReflectionMember.MemberName; FieldModel model = new FieldModel(xmlReflectionMember.MemberName, xmlReflectionMember.MemberType, typeScope.GetTypeDesc(xmlReflectionMember.MemberType), false, false); member.ReadOnly = model.ReadOnly || !model.FieldTypeDesc.HasDefaultConstructor; ImportAccessorMapping(member, model, a, ns, form); if (xmlReflectionMember.OverrideIsNullable) member.Elements[0].IsNullable = false; return member; }