SoapReflector.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Services / Web / System / Web / Services / Protocols / SoapReflector.cs / 1305376 / SoapReflector.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.Services.Protocols { 
    using System; 
    using System.Reflection;
    using System.Xml.Serialization; 
    using System.Collections;
    using System.Web.Services.Configuration;
    using System.Web.Services.Description;
    using System.Globalization; 
    using System.Xml;
    using System.Threading; 
 
    internal class SoapReflectedHeader {
        internal Type headerType; 
        internal MemberInfo memberInfo;
        internal SoapHeaderDirection direction;
        internal bool repeats;
        internal bool custom; 
    }
 
    internal class SoapReflectedExtension : IComparable { 
        Type type;
        SoapExtensionAttribute attribute; 
        int priority;

        internal SoapReflectedExtension(Type type, SoapExtensionAttribute attribute) : this(type, attribute, attribute.Priority) {}
 
        internal SoapReflectedExtension(Type type, SoapExtensionAttribute attribute, int priority) {
            if (priority < 0) throw new ArgumentException(Res.GetString(Res.WebConfigInvalidExtensionPriority, priority), "priority"); 
            this.type = type; 
            this.attribute = attribute;
            this.priority = priority; 
        }

        internal SoapExtension CreateInstance(object initializer) {
            SoapExtension extension = (SoapExtension)Activator.CreateInstance(type); 
            extension.Initialize(initializer);
            return extension; 
        } 

        internal object GetInitializer(LogicalMethodInfo methodInfo) { 
            SoapExtension extension = (SoapExtension)Activator.CreateInstance(type);
            return extension.GetInitializer(methodInfo, attribute);
        }
 
        internal object GetInitializer(Type serviceType) {
            SoapExtension extension = (SoapExtension) Activator.CreateInstance(type); 
            return extension.GetInitializer(serviceType); 
        }
 
        internal static object[] GetInitializers(LogicalMethodInfo methodInfo, SoapReflectedExtension[] extensions) {
            object[] initializers = new object[extensions.Length];
            for (int i = 0; i < initializers.Length; i++)
                initializers[i] = extensions[i].GetInitializer(methodInfo); 
            return initializers;
        } 
 
        internal static object[] GetInitializers(Type serviceType, SoapReflectedExtension[] extensions) {
            object[] initializers = new object[extensions.Length]; 
            for (int i = 0; i < initializers.Length; i++)
                initializers[i] = extensions[i].GetInitializer(serviceType);
            return initializers;
        } 

        public int CompareTo(object o) { 
            // higher priorities (lower numbers) go at the front of the list 
            return priority - ((SoapReflectedExtension)o).priority;
        } 
    }

    internal class SoapReflectedMethod {
        internal LogicalMethodInfo methodInfo; 
        internal string action;
        internal string name; 
        internal XmlMembersMapping requestMappings; 
        internal XmlMembersMapping responseMappings;
        internal XmlMembersMapping inHeaderMappings; 
        internal XmlMembersMapping outHeaderMappings;
        internal SoapReflectedHeader[] headers;
        internal SoapReflectedExtension[] extensions;
        internal bool oneWay; 
        internal bool rpc;
        internal SoapBindingUse use; 
        internal SoapParameterStyle paramStyle; 
        internal WebServiceBindingAttribute binding;
        internal XmlQualifiedName requestElementName; 
        internal XmlQualifiedName portType;
        internal bool IsClaimsConformance { get { return binding != null && binding.ConformsTo == WsiProfiles.BasicProfile1_1; } }
    }
 
    // custom attributes are not returned in a "stable" order, so we sort them by name
    internal class SoapHeaderAttributeComparer : IComparer { 
        public int Compare(object x, object y) { 
            return string.Compare(((SoapHeaderAttribute)x).MemberName, ((SoapHeaderAttribute)y).MemberName, StringComparison.Ordinal);
        } 
    }

    internal static class SoapReflector {
 
        class SoapParameterInfo {
            internal ParameterInfo parameterInfo; 
            internal XmlAttributes xmlAttributes; 
            internal SoapAttributes soapAttributes;
        } 

        class MethodAttribute {
            internal string action;
            internal string binding; 
            internal string requestName;
            internal string requestNs; 
            internal string responseName; 
            internal string responseNs;
        } 

        internal static bool ServiceDefaultIsEncoded(Type type){
            return ServiceDefaultIsEncoded(GetSoapServiceAttribute(type));
        } 

        internal static bool ServiceDefaultIsEncoded(object soapServiceAttribute) { 
            if (soapServiceAttribute == null) 
                return false;
            if (soapServiceAttribute is SoapDocumentServiceAttribute) { 
                return ((SoapDocumentServiceAttribute)soapServiceAttribute).Use == SoapBindingUse.Encoded;
            }
            if (soapServiceAttribute is SoapRpcServiceAttribute) {
                return ((SoapRpcServiceAttribute)soapServiceAttribute).Use == SoapBindingUse.Encoded; 
            }
            return false; 
        } 

        internal static string GetEncodedNamespace(string ns, bool serviceDefaultIsEncoded) { 
            if(serviceDefaultIsEncoded)
                return ns;
            if (ns.EndsWith("/", StringComparison.Ordinal))
                return ns + "encodedTypes"; 
            return ns + "/encodedTypes";
        } 
 
        internal static string GetLiteralNamespace(string ns, bool serviceDefaultIsEncoded) {
            if(!serviceDefaultIsEncoded) 
                return ns;
            if (ns.EndsWith("/", StringComparison.Ordinal))
                return ns + "literalTypes";
            return ns + "/literalTypes"; 
        }
 
        internal static SoapReflectionImporter CreateSoapImporter(string defaultNs, bool serviceDefaultIsEncoded) { 
            return new SoapReflectionImporter(GetEncodedNamespace(defaultNs, serviceDefaultIsEncoded));
        } 

        internal static XmlReflectionImporter CreateXmlImporter(string defaultNs, bool serviceDefaultIsEncoded) {
            return new XmlReflectionImporter(GetLiteralNamespace(defaultNs, serviceDefaultIsEncoded));
        } 

        internal static void IncludeTypes(LogicalMethodInfo[] methods, SoapReflectionImporter importer) { 
            for (int i = 0; i < methods.Length; i++) { 
                LogicalMethodInfo method = methods[i];
                IncludeTypes(method, importer); 
            }
        }

        internal static void IncludeTypes(LogicalMethodInfo method, SoapReflectionImporter importer) { 
            if (method.Declaration != null) {
                importer.IncludeTypes(method.Declaration.DeclaringType); 
                importer.IncludeTypes(method.Declaration); 
            }
            importer.IncludeTypes(method.DeclaringType); 
            importer.IncludeTypes(method.CustomAttributeProvider);
        }

        internal static object GetSoapMethodAttribute(LogicalMethodInfo methodInfo) { 
            object[] rpcMethodAttributes = methodInfo.GetCustomAttributes(typeof(SoapRpcMethodAttribute));
            object[] docMethodAttributes = methodInfo.GetCustomAttributes(typeof(SoapDocumentMethodAttribute)); 
            if (rpcMethodAttributes.Length > 0) { 
                if (docMethodAttributes.Length > 0) throw new ArgumentException(Res.GetString(Res.WebBothMethodAttrs), "methodInfo");
                return rpcMethodAttributes[0]; 
            }
            else if (docMethodAttributes.Length > 0)
                return docMethodAttributes[0];
            else 
                return null;
        } 
 
        internal static object GetSoapServiceAttribute(Type type) {
            object[] rpcServiceAttributes = type.GetCustomAttributes(typeof(SoapRpcServiceAttribute), false); 
            object[] docServiceAttributes = type.GetCustomAttributes(typeof(SoapDocumentServiceAttribute), false);
            if (rpcServiceAttributes.Length > 0) {
                if (docServiceAttributes.Length > 0) throw new ArgumentException(Res.GetString(Res.WebBothServiceAttrs), "methodInfo");
                return rpcServiceAttributes[0]; 
            }
            else if (docServiceAttributes.Length > 0) 
                return docServiceAttributes[0]; 
            else
                return null; 
        }

        internal static SoapServiceRoutingStyle GetSoapServiceRoutingStyle(object soapServiceAttribute) {
            if (soapServiceAttribute is SoapRpcServiceAttribute) 
                return ((SoapRpcServiceAttribute)soapServiceAttribute).RoutingStyle;
            else if (soapServiceAttribute is SoapDocumentServiceAttribute) 
                return ((SoapDocumentServiceAttribute)soapServiceAttribute).RoutingStyle; 
            else
                return SoapServiceRoutingStyle.SoapAction; 
        }

        internal static string GetSoapMethodBinding(LogicalMethodInfo method) {
            string binding; 
            object[] attrs = method.GetCustomAttributes(typeof(SoapDocumentMethodAttribute));
            if (attrs.Length == 0) { 
                attrs = method.GetCustomAttributes(typeof(SoapRpcMethodAttribute)); 
                if (attrs.Length == 0)
                    binding = string.Empty; 
                else
                    binding = ((SoapRpcMethodAttribute)attrs[0]).Binding;
            }
            else 
                binding = ((SoapDocumentMethodAttribute)attrs[0]).Binding;
 
            if (method.Binding != null) { 
                if (binding.Length > 0 && binding != method.Binding.Name) {
                    throw new InvalidOperationException(Res.GetString(Res.WebInvalidBindingName, binding, method.Binding.Name)); 
                }
                return method.Binding.Name;
            }
            return binding; 
        }
 
        internal static SoapReflectedMethod ReflectMethod(LogicalMethodInfo methodInfo, bool client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, string defaultNs) { 
            try {
                string methodId = methodInfo.GetKey(); 
                SoapReflectedMethod soapMethod = new SoapReflectedMethod();
                MethodAttribute methodAttribute = new MethodAttribute();

                object serviceAttr = GetSoapServiceAttribute(methodInfo.DeclaringType); 
                bool serviceDefaultIsEncoded = ServiceDefaultIsEncoded(serviceAttr);
                object methodAttr = GetSoapMethodAttribute(methodInfo); 
                if (methodAttr == null) { 
                    if (client) return null; // method attribute required on the client
                    if (serviceAttr is SoapRpcServiceAttribute) { 
                        SoapRpcMethodAttribute method = new SoapRpcMethodAttribute();
                        method.Use = ((SoapRpcServiceAttribute)serviceAttr).Use;
                        methodAttr = method;
                    } 
                    else if (serviceAttr is SoapDocumentServiceAttribute) {
                        SoapDocumentMethodAttribute method = new SoapDocumentMethodAttribute(); 
                        method.Use = ((SoapDocumentServiceAttribute)serviceAttr).Use; 
                        methodAttr = method;
                    } 
                    else {
                        methodAttr = new SoapDocumentMethodAttribute();
                    }
                } 

                if (methodAttr is SoapRpcMethodAttribute) { 
                    SoapRpcMethodAttribute attr = (SoapRpcMethodAttribute)methodAttr; 

                    soapMethod.rpc = true; 
                    soapMethod.use = attr.Use;
                    soapMethod.oneWay = attr.OneWay;
                    methodAttribute.action = attr.Action;
                    methodAttribute.binding = attr.Binding; 
                    methodAttribute.requestName = attr.RequestElementName;
                    methodAttribute.requestNs = attr.RequestNamespace; 
                    methodAttribute.responseName = attr.ResponseElementName; 
                    methodAttribute.responseNs = attr.ResponseNamespace;
                } 
                else {
                    SoapDocumentMethodAttribute attr = (SoapDocumentMethodAttribute)methodAttr;

                    soapMethod.rpc = false; 
                    soapMethod.use = attr.Use;
                    soapMethod.paramStyle = attr.ParameterStyle; 
                    soapMethod.oneWay = attr.OneWay; 
                    methodAttribute.action = attr.Action;
                    methodAttribute.binding = attr.Binding; 
                    methodAttribute.requestName = attr.RequestElementName;
                    methodAttribute.requestNs = attr.RequestNamespace;
                    methodAttribute.responseName = attr.ResponseElementName;
                    methodAttribute.responseNs = attr.ResponseNamespace; 

                    if (soapMethod.use == SoapBindingUse.Default) { 
                        if (serviceAttr is SoapDocumentServiceAttribute) 
                            soapMethod.use = ((SoapDocumentServiceAttribute)serviceAttr).Use;
                        if (soapMethod.use == SoapBindingUse.Default) 
                            soapMethod.use = SoapBindingUse.Literal;
                    }
                    if (soapMethod.paramStyle == SoapParameterStyle.Default) {
                        if (serviceAttr is SoapDocumentServiceAttribute) 
                            soapMethod.paramStyle = ((SoapDocumentServiceAttribute)serviceAttr).ParameterStyle;
                        if (soapMethod.paramStyle == SoapParameterStyle.Default) 
                            soapMethod.paramStyle = SoapParameterStyle.Wrapped; 
                    }
                } 

                if (methodAttribute.binding.Length > 0) {
                    if (client) throw new InvalidOperationException(Res.GetString(Res.WebInvalidBindingPlacement, methodAttr.GetType().Name));
                    soapMethod.binding = WebServiceBindingReflector.GetAttribute(methodInfo, methodAttribute.binding); 
                }
 
                WebMethodAttribute webMethodAttribute = methodInfo.MethodAttribute; 

                // 
                soapMethod.name = webMethodAttribute.MessageName;
                if (soapMethod.name.Length == 0) soapMethod.name = methodInfo.Name;

                string requestElementName; 
                if (soapMethod.rpc) {
                    // in the case when we interop with non .net we might need to chnage the method name. 
                    requestElementName = methodAttribute.requestName.Length == 0 || !client ? methodInfo.Name : methodAttribute.requestName; 
                }
                else { 
                    requestElementName = methodAttribute.requestName.Length == 0 ? soapMethod.name : methodAttribute.requestName;
                }
                string requestNamespace = methodAttribute.requestNs;
 
                if (requestNamespace == null){
                    if (soapMethod.binding != null && soapMethod.binding.Namespace != null && soapMethod.binding.Namespace.Length != 0) 
                        requestNamespace = soapMethod.binding.Namespace; 
                    else
                        requestNamespace = defaultNs; 
                }

                string responseElementName;
                if (soapMethod.rpc && soapMethod.use != SoapBindingUse.Encoded) 
                {
                    // NOTE: this rule should apply equally to rpc/lit and rpc/enc, but to reduce risk, i'm only applying it to rpc/lit 
                    responseElementName = methodInfo.Name + "Response"; 
                }
                else 
                {
                    responseElementName = methodAttribute.responseName.Length == 0 ? soapMethod.name + "Response" : methodAttribute.responseName;
                }
                string responseNamespace = methodAttribute.responseNs; 

                if (responseNamespace == null){ 
                    if (soapMethod.binding != null && soapMethod.binding.Namespace != null && soapMethod.binding.Namespace.Length != 0) 
                        responseNamespace = soapMethod.binding.Namespace;
                    else 
                        responseNamespace = defaultNs;
                }

                SoapParameterInfo[] inParameters = ReflectParameters(methodInfo.InParameters, requestNamespace); 
                SoapParameterInfo[] outParameters = ReflectParameters(methodInfo.OutParameters, responseNamespace);
 
                soapMethod.action = methodAttribute.action; 
                if (soapMethod.action == null)
                    soapMethod.action = GetDefaultAction(defaultNs, methodInfo); 
                soapMethod.methodInfo = methodInfo;

                if (soapMethod.oneWay) {
                    if (outParameters.Length > 0) throw new ArgumentException(Res.GetString(Res.WebOneWayOutParameters), "methodInfo"); 
                    if (methodInfo.ReturnType != typeof(void)) throw new ArgumentException(Res.GetString(Res.WebOneWayReturnValue), "methodInfo");
                } 
 
                XmlReflectionMember[] members = new XmlReflectionMember[inParameters.Length];
                for (int i = 0; i < members.Length; i++) { 
                    SoapParameterInfo soapParamInfo = inParameters[i];
                    XmlReflectionMember member = new XmlReflectionMember();
                    member.MemberName = soapParamInfo.parameterInfo.Name;
                    member.MemberType = soapParamInfo.parameterInfo.ParameterType; 
                    if (member.MemberType.IsByRef)
                        member.MemberType = member.MemberType.GetElementType(); 
                    member.XmlAttributes = soapParamInfo.xmlAttributes; 
                    member.SoapAttributes = soapParamInfo.soapAttributes;
                    members[i] = member; 
                }
                soapMethod.requestMappings = ImportMembersMapping(xmlImporter, soapImporter, serviceDefaultIsEncoded, soapMethod.rpc, soapMethod.use, soapMethod.paramStyle, requestElementName, requestNamespace, methodAttribute.requestNs == null, members, true, false, methodId, client);

                if (GetSoapServiceRoutingStyle(serviceAttr) == SoapServiceRoutingStyle.RequestElement && 
                    soapMethod.paramStyle == SoapParameterStyle.Bare &&
                    soapMethod.requestMappings.Count != 1) 
                    throw new ArgumentException(Res.GetString(Res.WhenUsingAMessageStyleOfParametersAsDocument0), "methodInfo"); 

                string elementName = ""; 
                string elementNamespace = "";
                if (soapMethod.paramStyle == SoapParameterStyle.Bare) {
                    if (soapMethod.requestMappings.Count == 1) {
                        elementName = soapMethod.requestMappings[0].XsdElementName; 
                        elementNamespace = soapMethod.requestMappings[0].Namespace;
                    } 
                    // else: can't route on request element -- we match on an empty qname, 
                    //       normal rules apply for duplicates
                } 
                else {
                    elementName = soapMethod.requestMappings.XsdElementName;
                    elementNamespace = soapMethod.requestMappings.Namespace;
                } 
                soapMethod.requestElementName = new XmlQualifiedName(elementName, elementNamespace);
 
                if (!soapMethod.oneWay) { 
                    int numOutParams = outParameters.Length;
                    int count = 0; 
                    CodeIdentifiers identifiers = null;
                    if (methodInfo.ReturnType != typeof(void)) {
                        numOutParams++;
                        count = 1; 
                        identifiers = new CodeIdentifiers();
                    } 
                    members = new XmlReflectionMember[numOutParams]; 

                    for (int i = 0; i < outParameters.Length; i++) { 
                        SoapParameterInfo soapParamInfo = outParameters[i];
                        XmlReflectionMember member = new XmlReflectionMember();
                        member.MemberName = soapParamInfo.parameterInfo.Name;
                        member.MemberType = soapParamInfo.parameterInfo.ParameterType; 
                        if (member.MemberType.IsByRef)
                            member.MemberType = member.MemberType.GetElementType(); 
                        member.XmlAttributes = soapParamInfo.xmlAttributes; 
                        member.SoapAttributes = soapParamInfo.soapAttributes;
                        members[count++] = member; 
                        if (identifiers != null)
                            identifiers.Add(member.MemberName, null);
                    }
                    if (methodInfo.ReturnType != typeof(void)) { 
                        XmlReflectionMember member = new XmlReflectionMember();
                        member.MemberName = identifiers.MakeUnique(soapMethod.name + "Result"); 
                        member.MemberType = methodInfo.ReturnType; 
                        member.IsReturnValue = true;
 
                        member.XmlAttributes = new XmlAttributes(methodInfo.ReturnTypeCustomAttributeProvider);
                        member.XmlAttributes.XmlRoot = null; // Ignore XmlRoot attribute used by get/post
                        member.SoapAttributes = new SoapAttributes(methodInfo.ReturnTypeCustomAttributeProvider);
 
                        members[0] = member;
                    } 
                    soapMethod.responseMappings = ImportMembersMapping(xmlImporter, soapImporter, serviceDefaultIsEncoded, soapMethod.rpc, soapMethod.use, soapMethod.paramStyle, responseElementName, responseNamespace, methodAttribute.responseNs == null, members, false, false, methodId + ":Response", !client); 

                } 

                SoapExtensionAttribute[] extensionAttributes = (SoapExtensionAttribute[])methodInfo.GetCustomAttributes(typeof(SoapExtensionAttribute));
                soapMethod.extensions = new SoapReflectedExtension[extensionAttributes.Length];
                for (int i = 0; i < extensionAttributes.Length; i++) 
                    soapMethod.extensions[i] = new SoapReflectedExtension(extensionAttributes[i].ExtensionType, extensionAttributes[i]);
                Array.Sort(soapMethod.extensions); 
 
                SoapHeaderAttribute[] headerAttributes = (SoapHeaderAttribute[])methodInfo.GetCustomAttributes(typeof(SoapHeaderAttribute));
                Array.Sort(headerAttributes, new SoapHeaderAttributeComparer()); 
                Hashtable headerTypes = new Hashtable();
                soapMethod.headers = new SoapReflectedHeader[headerAttributes.Length];
                int front = 0;
                int back = soapMethod.headers.Length; 
                ArrayList inHeaders = new ArrayList();
                ArrayList outHeaders = new ArrayList(); 
                for (int i = 0; i < soapMethod.headers.Length; i++) { 
                    SoapHeaderAttribute headerAttribute = headerAttributes[i];
                    SoapReflectedHeader soapHeader = new SoapReflectedHeader(); 
                    Type declaringType = methodInfo.DeclaringType;
                    if ((soapHeader.memberInfo = declaringType.GetField(headerAttribute.MemberName)) != null) {
                        soapHeader.headerType = ((FieldInfo)soapHeader.memberInfo).FieldType;
                    } 
                    else  if ((soapHeader.memberInfo = declaringType.GetProperty(headerAttribute.MemberName)) != null) {
                        soapHeader.headerType = ((PropertyInfo)soapHeader.memberInfo).PropertyType; 
                    } 
                    else {
                        throw HeaderException(headerAttribute.MemberName, methodInfo.DeclaringType, Res.WebHeaderMissing); 
                    }
                    if (soapHeader.headerType.IsArray) {
                        soapHeader.headerType = soapHeader.headerType.GetElementType();
                        soapHeader.repeats = true; 
                        if (soapHeader.headerType != typeof(SoapUnknownHeader) && soapHeader.headerType != typeof(SoapHeader))
                            throw HeaderException(headerAttribute.MemberName, methodInfo.DeclaringType, Res.WebHeaderType); 
                    } 
                    if (MemberHelper.IsStatic(soapHeader.memberInfo)) throw HeaderException(headerAttribute.MemberName, methodInfo.DeclaringType, Res.WebHeaderStatic);
                    if (!MemberHelper.CanRead(soapHeader.memberInfo)) throw HeaderException(headerAttribute.MemberName, methodInfo.DeclaringType, Res.WebHeaderRead); 
                    if (!MemberHelper.CanWrite(soapHeader.memberInfo)) throw HeaderException(headerAttribute.MemberName, methodInfo.DeclaringType, Res.WebHeaderWrite);
                    if (!typeof(SoapHeader).IsAssignableFrom(soapHeader.headerType)) throw HeaderException(headerAttribute.MemberName, methodInfo.DeclaringType, Res.WebHeaderType);

                    SoapHeaderDirection direction = headerAttribute.Direction; 
                    if (soapMethod.oneWay && (direction & (SoapHeaderDirection.Out | SoapHeaderDirection.Fault)) != 0) throw HeaderException(headerAttribute.MemberName, methodInfo.DeclaringType, Res.WebHeaderOneWayOut);
                    if (headerTypes.Contains(soapHeader.headerType)) { 
                        SoapHeaderDirection prevDirection = (SoapHeaderDirection) headerTypes[soapHeader.headerType]; 
                        if ((prevDirection & direction) != 0)
                            throw HeaderException(headerAttribute.MemberName, methodInfo.DeclaringType, Res.WebMultiplyDeclaredHeaderTypes); 
                        headerTypes[soapHeader.headerType] = direction | prevDirection;
                    }
                    else
                        headerTypes[soapHeader.headerType] = direction; 

                    if (soapHeader.headerType != typeof(SoapHeader) && soapHeader.headerType != typeof(SoapUnknownHeader)) { 
                        XmlReflectionMember member = new XmlReflectionMember(); 
                        member.MemberName = soapHeader.headerType.Name;
                        member.MemberType = soapHeader.headerType; 

                        XmlAttributes a = new XmlAttributes(soapHeader.headerType);
                        if (a.XmlRoot != null) {
                            member.XmlAttributes = new XmlAttributes(); 
                            XmlElementAttribute attr = new XmlElementAttribute();
                            attr.ElementName = a.XmlRoot.ElementName; 
                            attr.Namespace = a.XmlRoot.Namespace; 
                            member.XmlAttributes.XmlElements.Add(attr);
                        } 
                        member.OverrideIsNullable = true;

                        if ((direction & SoapHeaderDirection.In) != 0)
                            inHeaders.Add(member); 
                        if ((direction & (SoapHeaderDirection.Out | SoapHeaderDirection.Fault)) != 0)
                            outHeaders.Add(member); 
 
                        soapHeader.custom = true;
                    } 
                    soapHeader.direction = direction;
                    // Put generic header mappings at the end of the list so they are found last during header processing
                    if (!soapHeader.custom) {
                        soapMethod.headers[--back] = soapHeader; 
                    }
                    else { 
                        soapMethod.headers[front++] = soapHeader; 
                    }
                } 
                soapMethod.inHeaderMappings = ImportMembersMapping(xmlImporter, soapImporter, serviceDefaultIsEncoded, false, soapMethod.use, SoapParameterStyle.Bare, requestElementName + "InHeaders", defaultNs, true, (XmlReflectionMember[]) inHeaders.ToArray(typeof(XmlReflectionMember)), false, true, methodId + ":InHeaders", client);
                if (!soapMethod.oneWay)
                    soapMethod.outHeaderMappings = ImportMembersMapping(xmlImporter, soapImporter, serviceDefaultIsEncoded, false, soapMethod.use, SoapParameterStyle.Bare, responseElementName + "OutHeaders", defaultNs, true, (XmlReflectionMember[]) outHeaders.ToArray(typeof(XmlReflectionMember)), false, true, methodId + ":OutHeaders", !client);
 
                return soapMethod;
            } 
            catch (Exception e) { 
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw; 
                }
                throw new InvalidOperationException(Res.GetString(Res.WebReflectionErrorMethod, methodInfo.DeclaringType.Name, methodInfo.Name), e);
            }
        } 

        static XmlMembersMapping ImportMembersMapping(XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, bool serviceDefaultIsEncoded, bool rpc, SoapBindingUse use, SoapParameterStyle paramStyle, 
            string elementName, string elementNamespace, bool nsIsDefault, XmlReflectionMember[] members, bool validate, bool openModel, string key, bool writeAccess) { 
            XmlMembersMapping mapping = null;
            if (use == SoapBindingUse.Encoded) { 
                string ns = (!rpc && paramStyle != SoapParameterStyle.Bare && nsIsDefault) ? GetEncodedNamespace(elementNamespace, serviceDefaultIsEncoded) : elementNamespace;
                mapping = soapImporter.ImportMembersMapping(elementName, ns, members, rpc || paramStyle != SoapParameterStyle.Bare, rpc, validate, writeAccess ? XmlMappingAccess.Write : XmlMappingAccess.Read);
            }
            else { 
                string ns =  nsIsDefault ? GetLiteralNamespace(elementNamespace, serviceDefaultIsEncoded) : elementNamespace;
                mapping = xmlImporter.ImportMembersMapping(elementName, ns, members, paramStyle != SoapParameterStyle.Bare, rpc, openModel, writeAccess ? XmlMappingAccess.Write : XmlMappingAccess.Read); 
            } 
            if (mapping != null) {
                mapping.SetKey(key); 
            }
            return mapping;
        }
 
        static Exception HeaderException(string memberName, Type declaringType, string description) {
            return new Exception(Res.GetString(description, declaringType.Name, memberName)); 
        } 

        static SoapParameterInfo[] ReflectParameters(ParameterInfo[] paramInfos, string ns) { 
            SoapParameterInfo[] soapParamInfos = new SoapParameterInfo[paramInfos.Length];
            for (int i = 0; i < paramInfos.Length; i++) {
                SoapParameterInfo soapParamInfo = new SoapParameterInfo();
 
                ParameterInfo paramInfo = paramInfos[i];
 
                if (paramInfo.ParameterType.IsArray && paramInfo.ParameterType.GetArrayRank() > 1) 
                    throw new InvalidOperationException(Res.GetString(Res.WebMultiDimArray));
 
                soapParamInfo.xmlAttributes = new XmlAttributes(paramInfo);
                soapParamInfo.soapAttributes = new SoapAttributes(paramInfo);
                soapParamInfo.parameterInfo = paramInfo;
                soapParamInfos[i] = soapParamInfo; 
            }
            return soapParamInfos; 
        } 

        static string GetDefaultAction(string defaultNs, LogicalMethodInfo methodInfo) { 
            WebMethodAttribute methodAttribute = methodInfo.MethodAttribute;
            string messageName = methodAttribute.MessageName;
            if (messageName.Length == 0) messageName = methodInfo.Name;
            if (defaultNs.EndsWith("/", StringComparison.Ordinal)) 
                return defaultNs + messageName;
            return defaultNs + "/" + messageName; 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK