private void ProcessAttributes(ParseRecord pr, ParseRecord objectPr) { InternalST.Soap( this, "ProcessAttributes Entry ",pr.Trace()," headerState ",((Enum)headerState).ToString()); String keyPosition = null; String keyOffset = null; String keyMustUnderstand = null; pr.PRisProcessAttributes = true; String SoapKeyUrl = "http://schemas.xmlsoap.org/soap/encoding/"; int SoapKeyUrlLength = SoapKeyUrl.Length; String UrtKeyUrl = "http://schemas.microsoft.com/clr/id"; int UrtKeyUrlLength = UrtKeyUrl.Length; String SoapEnvKeyUrl = "http://schemas.xmlsoap.org/soap/envelope/"; int SoapEnvKeyUrlLength = SoapEnvKeyUrl.Length; String XSIKey2001 = "http://www.w3.org/2001/XMLSchema-instance"; int XSIKey2001Length = XSIKey2001.Length; String XSIKey2000 = "http://www.w3.org/2000/10/XMLSchema-instance"; int XSIKey2000Length = XSIKey2000.Length; String XSIKey1999 = "http://www.w3.org/1999/XMLSchema-instance"; int XSIKey1999Length = XSIKey1999.Length; String XSDKey1999 = "http://www.w3.org/1999/XMLSchema"; int XSDKey1999Length = XSDKey1999.Length; String XSDKey2000 = "http://www.w3.org/2000/10/XMLSchema"; int XSDKey2000Length = XSDKey2000.Length; String XSDKey2001 = "http://www.w3.org/2001/XMLSchema"; int XSDKey2001Length = XSDKey2001.Length; String clrNS = "http://schemas.microsoft.com/soap/encoding/clr/1.0"; int clrNSLength = clrNS.Length; for (int i = 0; i<attributeValues.Count(); i++) { AttributeValueEntry attributeValueEntry = (AttributeValueEntry)attributeValues.GetItem(i); String prefix = attributeValueEntry.prefix; String key = attributeValueEntry.key; if ((key == null) || (key.Length == 0)) key = pr.PRnameXmlKey; //case where there is a default key String value = attributeValueEntry.value; bool prefixMatchesXmlns = false; String urn = attributeValueEntry.urn; InternalST.Soap( this, "ProcessAttributes attribute prefix ",prefix," key ",key," value ",value," urn ", urn); int keyLength = key.Length; int valueLength = value.Length; // table need for QName xsd types if (key == null || keyLength == 0) keyToNamespaceTable[prefix] = value; else keyToNamespaceTable[prefix+":"+key] = value; if (keyLength == 2 && String.Compare(key, "id", true, CultureInfo.InvariantCulture) == 0) pr.PRobjectId = objectReader.GetId(value); else if (keyLength == 8 && String.Compare(key, "position", true, CultureInfo.InvariantCulture) == 0) keyPosition = value; else if (keyLength == 6 && String.Compare(key, "offset", true, CultureInfo.InvariantCulture) == 0) keyOffset = value; else if (keyLength == 14 && String.Compare(key, "MustUnderstand", true, CultureInfo.InvariantCulture) == 0) keyMustUnderstand = value; else if (keyLength == 4 && String.Compare(key, "null", true, CultureInfo.InvariantCulture) == 0) { pr.PRmemberValueEnum = InternalMemberValueE.Null; pr.PRvalue = null; } else if (keyLength == 4 && String.Compare(key, "root", true, CultureInfo.InvariantCulture) == 0) { if (value.Equals("1")) pr.PRisHeaderRoot = true; } else if (keyLength == 4 && String.Compare(key, "href", true, CultureInfo.InvariantCulture) == 0) pr.PRidRef = objectReader.GetId(value); else if (keyLength == 4 && String.Compare(key, "type", true, CultureInfo.InvariantCulture) == 0) { String currentPRtypeXmlKey = pr.PRtypeXmlKey; String currentPRkeyDt = pr.PRkeyDt; Type currentPRdtType = pr.PRdtType; String typeValue = value; int index = value.IndexOf(":"); if (index > 0) { pr.PRtypeXmlKey = value.Substring(0, index); typeValue = value.Substring(++index); } else { pr.PRtypeXmlKey = prefix; } if (String.Compare(typeValue, "anyType", true, CultureInfo.InvariantCulture) == 0 || String.Compare(typeValue, "ur-type", true, CultureInfo.InvariantCulture) == 0) { pr.PRkeyDt = "System.Object"; pr.PRdtType = SoapUtil.typeofObject; pr.PRtypeXmlKey = urtKey; } if (pr.PRtypeXmlKey == soapKey && typeValue == "Array") //Don't need to process xsi:type="SOAP-ENC:Array" { // Array values already found,use these value rather then the xsi:type values pr.PRtypeXmlKey = currentPRtypeXmlKey; pr.PRkeyDt = currentPRkeyDt; pr.PRdtType = currentPRdtType; InternalST.Soap( this,"ProcessAttributes, xsi:type='SOAP-ENC:Array' pr.PRtypeXmlKey ", pr.PRtypeXmlKey," pr.PRkeyDt "+pr.PRkeyDt); } else { pr.PRkeyDt = typeValue; InternalST.Soap( this,"ProcessAttributes, not xsi:type='SOAP-ENC:Array' pr.PRtypeXmlKey ", pr.PRtypeXmlKey," pr.PRkeyDt "+pr.PRkeyDt); } } else if (keyLength == 9 && String.Compare(key, "arraytype", true, CultureInfo.InvariantCulture) == 0) { String typeValue = value; int index = value.IndexOf(":"); if (index > 0) { pr.PRtypeXmlKey = value.Substring(0, index); pr.PRkeyDt = typeValue = value.Substring(++index); } if (typeValue.StartsWith("ur_type[")) { pr.PRkeyDt = "System.Object"+typeValue.Substring(6); pr.PRtypeXmlKey = urtKey; } } else if (SoapServices.IsClrTypeNamespace(value)) { if (!assemKeyToAssemblyTable.ContainsKey(key)) { String typeNamespace = null; String assemblyName = null; SoapServices.DecodeXmlNamespaceForClrTypeNamespace(value, out typeNamespace, out assemblyName); if (assemblyName == null) { assemKeyToAssemblyTable[key] = new SoapAssemblyInfo(SoapUtil.urtAssemblyString, SoapUtil.urtAssembly); assemKeyToNameSpaceTable[key] = typeNamespace; } else { assemKeyToAssemblyTable[key] = new SoapAssemblyInfo(assemblyName); if (typeNamespace != null) assemKeyToNameSpaceTable[key] = typeNamespace; } } } else if ((prefixMatchesXmlns = prefix.Equals("xmlns")) && (valueLength == SoapKeyUrlLength && String.Compare(value, SoapKeyUrl, true, CultureInfo.InvariantCulture) == 0)) { soapKey = key; } else if (prefixMatchesXmlns && (valueLength == UrtKeyUrlLength && String.Compare(value, UrtKeyUrl, true, CultureInfo.InvariantCulture) == 0)) { urtKey = key; assemKeyToAssemblyTable[urtKey] = new SoapAssemblyInfo(SoapUtil.urtAssemblyString, SoapUtil.urtAssembly); } else if (prefixMatchesXmlns && (valueLength == SoapEnvKeyUrlLength && String.Compare(value, SoapEnvKeyUrl, true) == 0)) { soapEnvKey = key; } else if (key == "encodingStyle") { /* String[] split = value.Split(' '); foreach (String s in split) { if (s == "http://schemas.microsoft.com/soap/encoding/clr/1.0") { objectReader.SetVersion(1,0); break; } } */ } else if (prefixMatchesXmlns && ((valueLength == XSIKey2001Length && String.Compare(value, XSIKey2001,true, CultureInfo.InvariantCulture) == 0) || (valueLength == XSIKey1999Length && String.Compare(value, XSIKey1999,true, CultureInfo.InvariantCulture) == 0) || (valueLength == XSIKey2000Length && String.Compare(value, XSIKey2000,true, CultureInfo.InvariantCulture) == 0))) { xsiKey = key; } else if (prefixMatchesXmlns && ((valueLength == XSDKey2001Length && String.Compare(value, XSDKey2001 , true, CultureInfo.InvariantCulture) == 0)) || (valueLength == XSDKey1999Length && String.Compare(value, XSDKey1999, true, CultureInfo.InvariantCulture) == 0) || (valueLength == XSDKey2000Length && String.Compare(value, XSDKey2000, true, CultureInfo.InvariantCulture) == 0)) { xsdKey = key; } else if (prefixMatchesXmlns && (valueLength == clrNSLength && String.Compare(value, clrNS, true, CultureInfo.InvariantCulture) == 0)) { objectReader.SetVersion(1,0); } else { //String lowerCaseValue = value.ToLower(CultureInfo.InvariantCulture); if (prefixMatchesXmlns) { // Assume it is an interop namespace assemKeyToInteropAssemblyTable[key] = value; InternalST.Soap( this,"ProcessAttributes, InteropType key "+key+" value ",value); } else if (String.Compare(prefix, soapKey, true, CultureInfo.InvariantCulture) == 0) { InternalST.Soap( this,"ProcessAttributes, Not processed key ",prefix,":",key," = ",value); } else { // See if it is a XmlAttribute InternalST.Soap( this,"ProcessAttributes, XmlAttribute prefix ",prefix," key ",key," value ",value," urn ",urn, " hashtable ",assemKeyToInteropAssemblyTable[prefix]); if ((assemKeyToInteropAssemblyTable.ContainsKey(prefix)) && ((String)assemKeyToInteropAssemblyTable[prefix]).Equals(urn)) { ProcessXmlAttribute(prefix, key, value, objectPr); } else { InternalST.Soap( this,"ProcessAttributes, Not processed prefix ",prefix," key ",key," value ",value," urn ",urn); } } } } attributeValues.Clear(); // reset the header state // If no headers then headerState is None // // if parent is a header section then these are top level objects // within the header section. If the object has a root set // then it is a header record, if not then it is a toplevel object // in the header section which is not a header record. // // if the parent is not a header section and is a header root // then this is a nested object within a header record. All // subsequent object will be nested until another header // root is encountered // // The first header record is considered a root record if (headerState != HeaderStateEnum.None) { if (objectPr.PRparseTypeEnum == InternalParseTypeE.Headers) { if (pr.PRisHeaderRoot || (headerState == HeaderStateEnum.FirstHeaderRecord)) { headerState = HeaderStateEnum.HeaderRecord; } else { headerState = HeaderStateEnum.TopLevelObject; currentState = InternalParseStateE.Object; pr.PRobjectTypeEnum = InternalObjectTypeE.Object; pr.PRparseTypeEnum = InternalParseTypeE.Object; pr.PRparseStateEnum = InternalParseStateE.Object; pr.PRmemberTypeEnum = InternalMemberTypeE.Empty; pr.PRmemberValueEnum = InternalMemberValueE.Empty; } } else if (objectPr.PRisHeaderRoot) headerState = HeaderStateEnum.NestedObject; } InternalST.Soap( this,"ProcessAttributes, headerState ",((Enum)headerState).ToString()); if (!isTopFound && (objectPr != null ) && (objectPr.PRparseTypeEnum == InternalParseTypeE.Body)) { pr.PRobjectPositionEnum = InternalObjectPositionE.Top; isTopFound = true; } else if (pr.PRobjectPositionEnum != InternalObjectPositionE.Top) pr.PRobjectPositionEnum = InternalObjectPositionE.Child; // Don't process type for envelop, topSoapElement unless it has a key of soapEnvKey (SOAP-ENV). Fault // is the only top record which currently falls into this category. if (!((pr.PRparseTypeEnum == InternalParseTypeE.Envelope)|| (pr.PRparseTypeEnum == InternalParseTypeE.Body) || (pr.PRparseTypeEnum == InternalParseTypeE.Headers) || (pr.PRobjectPositionEnum == InternalObjectPositionE.Top && objectReader.IsFakeTopObject && !pr.PRnameXmlKey.Equals(soapEnvKey)))) { InternalST.Soap( this, "ProcessAttributes before Process Type ",((Enum)pr.PRparseTypeEnum).ToString()); ProcessType(pr, objectPr); } if (keyPosition != null) { int outRank; String outDimSignature; InternalArrayTypeE outArrayTypeEnum; pr.PRpositionA = ParseArrayDimensions(keyPosition, out outRank, out outDimSignature, out outArrayTypeEnum); } if (keyOffset != null) { int outRank; String outDimSignature; InternalArrayTypeE outArrayTypeEnum; pr.PRlowerBoundA = ParseArrayDimensions(keyOffset, out outRank, out outDimSignature, out outArrayTypeEnum); } if (keyMustUnderstand != null) if (keyMustUnderstand.Equals("1")) pr.PRisMustUnderstand = true; else if (keyMustUnderstand.Equals("0")) pr.PRisMustUnderstand = false; else throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_MustUnderstand"),keyMustUnderstand)); if (pr.PRparseTypeEnum == InternalParseTypeE.Member) { // Process Member InternalST.Soap( this, "ProcessAttributes Member "); stack.Dump(); if (objectPr.PRparseTypeEnum == InternalParseTypeE.Headers) pr.PRmemberTypeEnum = InternalMemberTypeE.Header; else if (objectPr.PRobjectTypeEnum == InternalObjectTypeE.Array) pr.PRmemberTypeEnum = InternalMemberTypeE.Item; else pr.PRmemberTypeEnum = InternalMemberTypeE.Field; } }
internal void Init(ObjectReader objectReader) { this.objectReader = objectReader; objectReader.soapHandler = this; isEnvelope = false; isBody = false; isTopFound = false; attributeValues.Clear(); assemKeyToAssemblyTable = new Hashtable(10); assemKeyToAssemblyTable[urtKey] = new SoapAssemblyInfo(SoapUtil.urtAssemblyString, SoapUtil.urtAssembly); assemKeyToNameSpaceTable = new Hashtable(10); assemKeyToInteropAssemblyTable = new Hashtable(10); nameSpaceToKey = new Hashtable(5); keyToNamespaceTable = new Hashtable(10); }