/// <summary>
        /// Reads a Fault reply from the service.
        /// </summary>
        /// <param name="reader">The reader, which should start at the "Fault" element.</param>
        /// <param name="operationName">Name of the operation.</param>
        /// <returns>A FaultException with the details in the server reply</returns>
        private static FaultException <DomainServiceFault> ReadFaultException(System.Xml.XmlDictionaryReader reader, string operationName)
        {
            FaultCode              faultCode;
            FaultReason            faultReason;
            List <FaultReasonText> faultReasons = new List <FaultReasonText>();

            reader.ReadStartElement("Fault"); // <Fault>
            reader.ReadStartElement("Code");  // <Code>
            reader.ReadStartElement("Value"); // <Value>
            faultCode = new FaultCode(reader.ReadContentAsString());
            reader.ReadEndElement();          // </Value>
            reader.ReadEndElement();          // </Code>

            reader.ReadStartElement("Reason");
            while (reader.LocalName == "Text")
            {
                var lang = reader.XmlLang;
                reader.ReadStartElement("Text");
                var text = reader.ReadContentAsString();
                reader.ReadEndElement();

                faultReasons.Add(new FaultReasonText(text, lang));
            }
            reader.ReadEndElement(); // </Reason>
            faultReason = new FaultReason(faultReasons);

            reader.ReadStartElement("Detail"); // <Detail>
            var fault = (DomainServiceFault)s_faultSerializer.ReadObject(reader);

            return(new FaultException <DomainServiceFault>(fault, faultReason, faultCode, operationName));
        }
Ejemplo n.º 2
0
        private object DeserializeArrayXmlSerializer(System.Xml.XmlDictionaryReader xmlReader, Type parameterType, string parameterName, string parameterNs, ICustomAttributeProvider customAttributeProvider)
        {
            var xmlArrayAttributes = customAttributeProvider.GetCustomAttributes(typeof(XmlArrayItemAttribute), true);
            XmlArrayItemAttribute xmlArrayItemAttribute = xmlArrayAttributes.FirstOrDefault() as XmlArrayItemAttribute;
            var xmlElementAttributes = customAttributeProvider.GetCustomAttributes(typeof(XmlElementAttribute), true);
            XmlElementAttribute xmlElementAttribute = xmlElementAttributes.FirstOrDefault() as XmlElementAttribute;

            var isEmpty             = xmlReader.IsEmptyElement;
            var hasContainerElement = xmlElementAttribute == null;

            if (hasContainerElement)
            {
                xmlReader.ReadStartElement(parameterName, parameterNs);
            }

            var elementType = parameterType.GetElementType();

            var arrayItemName = xmlArrayItemAttribute?.ElementName ?? xmlElementAttribute?.ElementName ?? elementType.Name;

            if (xmlArrayItemAttribute?.ElementName == null && elementType.Namespace?.StartsWith("System") == true)
            {
                var compiler = new CSharpCodeProvider();
                var type     = new CodeTypeReference(elementType);
                arrayItemName = compiler.GetTypeOutput(type);
            }

            var deserializeMethod  = typeof(XmlSerializerExtensions).GetGenericMethod(nameof(XmlSerializerExtensions.DeserializeArray), elementType);
            var arrayItemNamespace = xmlArrayItemAttribute?.Namespace ?? parameterNs;

            var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, arrayItemName, arrayItemNamespace);

            object result = null;

            lock (serializer)
            {
                if (xmlReader.HasValue && elementType?.FullName == "System.Byte")
                {
                    result = xmlReader.ReadContentAsBase64();
                }
                else
                {
                    result = deserializeMethod.Invoke(null, new object[] { serializer, arrayItemName, arrayItemNamespace, xmlReader });
                }
            }

            if (!isEmpty && hasContainerElement)
            {
                xmlReader.ReadEndElement();
            }

            return(result);
        }
Ejemplo n.º 3
0
 public override object ReadObject(System.Xml.XmlDictionaryReader reader, bool verifyObjectName)
 {
     if (reader.GetAttribute("nil") == "true")
     {
         return(null);
     }
     reader.ReadStartElement(PROTO_ELEMENT);
     try
     {
         using (MemoryStream ms = new MemoryStream(reader.ReadContentAsBase64()))
         {
             T val = Serializer.Deserialize <T>(ms);
             return(val);
         }
     }
     finally
     {
         reader.ReadEndElement();
     }
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Reads the body of an object
 /// </summary>
 public override object ReadObject(System.Xml.XmlDictionaryReader reader, bool verifyObjectName)
 {
     if (reader.GetAttribute("nil") == "true")
     {
         return(null);
     }
     reader.ReadStartElement(PROTO_ELEMENT);
     try
     {
         using (MemoryStream ms = new MemoryStream(reader.ReadContentAsBase64()))
         {
             using (ProtoReader protoReader = new ProtoReader(ms, model, null))
             {
                 return(model.Deserialize(key, null, protoReader));
             }
         }
     }
     finally
     {
         reader.ReadEndElement();
     }
 }
Ejemplo n.º 5
0
        private object DeserializeArray(System.Xml.XmlDictionaryReader xmlReader, Type parameterType, string parameterName, string parameterNs, SoapMethodParameterInfo parameterInfo)
        {
            var isEmpty = xmlReader.IsEmptyElement;
            //if (parameterInfo.ArrayItemName != null)
            {
                xmlReader.ReadStartElement(parameterName, parameterNs);
            }

            var elementType = parameterType.GetElementType();

            var localName = parameterInfo.ArrayItemName ?? elementType.Name;

            if (parameterInfo.ArrayItemName == null && elementType.Namespace.StartsWith("System"))
            {
                var compiler = new CSharpCodeProvider();
                var type     = new CodeTypeReference(elementType);
                localName = compiler.GetTypeOutput(type);
            }

            //localName = "ComplexModelInput";
            var deserializeMethod = typeof(XmlSerializerExtensions).GetGenericMethod(nameof(XmlSerializerExtensions.DeserializeArray), elementType);
            var serializer        = CachedXmlSerializer.GetXmlSerializer(elementType, localName, parameterNs);

            object result = null;

            lock (serializer)
            {
                result = deserializeMethod.Invoke(null, new object[] { serializer, localName, parameterNs, xmlReader });
            }

            //if (parameterInfo.ArrayItemName != null)
            if (!isEmpty)
            {
                xmlReader.ReadEndElement();
            }

            return(result);
        }
Ejemplo n.º 6
0
        private object DeserializeArrayXmlSerializer(System.Xml.XmlDictionaryReader xmlReader, Type parameterType, string parameterName, string parameterNs, MemberInfo memberInfo)
        {
            XmlArrayItemAttribute xmlArrayItemAttribute = memberInfo.GetCustomAttribute(typeof(XmlArrayItemAttribute)) as XmlArrayItemAttribute;

            var isEmpty = xmlReader.IsEmptyElement;

            xmlReader.ReadStartElement(parameterName, parameterNs);

            var elementType = parameterType.GetElementType();

            var arrayItemName = xmlArrayItemAttribute?.ElementName ?? elementType.Name;

            if (xmlArrayItemAttribute?.ElementName == null && elementType.Namespace?.StartsWith("System") == true)
            {
                var compiler = new CSharpCodeProvider();
                var type     = new CodeTypeReference(elementType);
                arrayItemName = compiler.GetTypeOutput(type);
            }

            var deserializeMethod  = typeof(XmlSerializerExtensions).GetGenericMethod(nameof(XmlSerializerExtensions.DeserializeArray), elementType);
            var arrayItemNamespace = xmlArrayItemAttribute?.Namespace ?? parameterNs;

            var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, arrayItemName, arrayItemNamespace);

            object result = null;

            lock (serializer)
            {
                result = deserializeMethod.Invoke(null, new object[] { serializer, arrayItemName, arrayItemNamespace, xmlReader });
            }

            if (!isEmpty)
            {
                xmlReader.ReadEndElement();
            }

            return(result);
        }
Ejemplo n.º 7
0
        private object[] GetRequestArguments(Message requestMessage, System.Xml.XmlDictionaryReader xmlReader, OperationDescription operation, ref Dictionary <string, object> outArgs)
        {
            var parameters = operation.NormalParameters;
            // avoid reallocation
            var arguments = new List <object>(parameters.Length + operation.OutParameters.Length);

            // Find the element for the operation's data
            xmlReader.ReadStartElement(operation.Name, operation.Contract.Namespace);

            for (int i = 0; i < parameters.Length; i++)
            {
                var parameterName = parameters[i].Name;
                var parameterNs   = parameters[i].Namespace;

                if (xmlReader.IsStartElement(parameterName, parameterNs))
                {
                    xmlReader.MoveToStartElement(parameterName, parameterNs);

                    if (xmlReader.IsStartElement(parameterName, parameterNs))
                    {
                        var elementType = parameters[i].Parameter.ParameterType.GetElementType();
                        if (elementType == null || parameters[i].Parameter.ParameterType.IsArray)
                        {
                            elementType = parameters[i].Parameter.ParameterType;
                        }

                        switch (_serializer)
                        {
                        case SoapSerializer.XmlSerializer:
                        {
                            // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
                            var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, parameterName, parameterNs);
                            lock (serializer)
                                arguments.Add(serializer.Deserialize(xmlReader));
                        }
                        break;

                        case SoapSerializer.DataContractSerializer:
                        {
                            var serializer = new DataContractSerializer(elementType, parameterName, parameterNs);
                            arguments.Add(serializer.ReadObject(xmlReader, verifyObjectName: true));
                        }
                        break;

                        default: throw new NotImplementedException();
                        }
                    }
                }
                else
                {
                    arguments.Add(null);
                }
            }

            foreach (var parameterInfo in operation.OutParameters)
            {
                if (parameterInfo.Parameter.ParameterType.Name == "Guid&")
                {
                    outArgs[parameterInfo.Name] = Guid.Empty;
                }
                else if (parameterInfo.Parameter.ParameterType.Name == "String&" || parameterInfo.Parameter.ParameterType.GetElementType().IsArray)
                {
                    outArgs[parameterInfo.Name] = null;
                }
                else
                {
                    var type = parameterInfo.Parameter.ParameterType.GetElementType();
                    outArgs[parameterInfo.Name] = Activator.CreateInstance(type);
                }
            }
            return(arguments.ToArray());
        }
        private object[] GetRequestArguments(Message requestMessage, System.Xml.XmlDictionaryReader xmlReader, OperationDescription operation, HttpContext httpContext)
        {
            var arguments = new object[operation.AllParameters.Length];

            // if any ordering issues, possible to rewrite like:

            /*while (!xmlReader.EOF)
             * {
             *      var parameterInfo = operation.InParameters.FirstOrDefault(p => p.Name == xmlReader.LocalName && p.Namespace == xmlReader.NamespaceURI);
             *      if (parameterInfo == null)
             *      {
             *              xmlReader.Skip();
             *              continue;
             *      }
             *      var parameterName = parameterInfo.Name;
             *      var parameterNs = parameterInfo.Namespace;
             *      ...
             * }*/

            // Find the element for the operation's data
            if (!operation.IsMessageContractRequest)
            {
                xmlReader.ReadStartElement(operation.Name, operation.Contract.Namespace);

                foreach (var parameterInfo in operation.InParameters)
                {
                    var @namespace    = parameterInfo.Namespace ?? operation.Contract.Namespace;
                    var parameterType = parameterInfo.Parameter.ParameterType;

                    if (parameterType == typeof(HttpContext))
                    {
                        arguments[parameterInfo.Index] = httpContext;
                    }
                    else
                    {
                        arguments[parameterInfo.Index] = DeserializeInputParameter(xmlReader, parameterType, parameterInfo.Name, @namespace, parameterInfo);
                    }
                }
            }
            else
            {
                // MessageContracts are constrained to having one "InParameter". We can do special logic on
                // for this
                Debug.Assert(operation.InParameters.Length == 1, "MessageContracts are constrained to having one 'InParameter'");

                var parameterInfo = operation.InParameters[0];
                var parameterType = parameterInfo.Parameter.ParameterType;

                var messageContractAttribute = parameterType.GetCustomAttribute <MessageContractAttribute>();

                Debug.Assert(messageContractAttribute != null, "operation.IsMessageContractRequest should be false if this is null");

                var @namespace = parameterInfo.Namespace ?? operation.Contract.Namespace;

                if (messageContractAttribute.IsWrapped)
                {
                    // It's wrapped so we treat it like normal!
                    arguments[parameterInfo.Index] = DeserializeInputParameter(xmlReader, parameterInfo.Parameter.ParameterType, parameterInfo.Name, @namespace, parameterInfo);
                }
                else
                {
                    // This object isn't a wrapper element, so we will hunt for the nested message body
                    // member inside of it
                    var messageBodyMembers =
                        parameterType
                        .GetPropertyOrFieldMembers()
                        .Select(mi => new
                    {
                        Member = mi,
                        MessageBodyMemberAttribute = mi.GetCustomAttribute <MessageBodyMemberAttribute>()
                    })
                        .OrderBy(x => x.MessageBodyMemberAttribute.Order);

                    var wrapperObject = Activator.CreateInstance(parameterInfo.Parameter.ParameterType);

                    foreach (var messageBodyMember in messageBodyMembers)
                    {
                        var messageBodyMemberAttribute = messageBodyMember.MessageBodyMemberAttribute;
                        var messageBodyMemberInfo      = messageBodyMember.Member;

                        var innerParameterName = messageBodyMemberAttribute.Name ?? messageBodyMemberInfo.Name;
                        var innerParameterNs   = messageBodyMemberAttribute.Namespace;
                        var innerParameterType = messageBodyMemberInfo.GetPropertyOrFieldType();

                        var innerParameter = DeserializeInputParameter(xmlReader, innerParameterType, innerParameterName, innerParameterNs, parameterInfo);

                        if (messageBodyMemberInfo is FieldInfo fi)
                        {
                            fi.SetValue(wrapperObject, innerParameter);
                        }
                        else if (messageBodyMemberInfo is PropertyInfo pi)
                        {
                            pi.SetValue(wrapperObject, innerParameter);
                        }
                        else
                        {
                            throw new NotImplementedException("Cannot set value of parameter type from " + messageBodyMemberInfo.GetType()?.Name);
                        }
                    }

                    arguments[parameterInfo.Index] = wrapperObject;
                }
            }

            foreach (var parameterInfo in operation.OutParameters)
            {
                if (arguments[parameterInfo.Index] != null)
                {
                    // do not overwrite input ref parameters
                    continue;
                }

                if (parameterInfo.Parameter.ParameterType.Name == "Guid&")
                {
                    arguments[parameterInfo.Index] = Guid.Empty;
                }
                else if (parameterInfo.Parameter.ParameterType.Name == "String&" || parameterInfo.Parameter.ParameterType.GetElementType().IsArray)
                {
                    arguments[parameterInfo.Index] = null;
                }
                else
                {
                    var type = parameterInfo.Parameter.ParameterType.GetElementType();
                    arguments[parameterInfo.Index] = Activator.CreateInstance(type);
                }
            }

            return(arguments);
        }
Ejemplo n.º 9
0
        private object[] GetRequestArguments(Message requestMessage, System.Xml.XmlDictionaryReader xmlReader, OperationDescription operation, ref Dictionary <string, object> outArgs)
        {
            var parameters = operation.DispatchMethod.GetParameters().Where(x => !x.IsOut && !x.ParameterType.IsByRef).ToArray();
            var arguments  = new List <object>();

            // Find the element for the operation's data
            xmlReader.ReadStartElement(operation.Name, operation.Contract.Namespace);

            for (int i = 0; i < parameters.Length; i++)
            {
                var elementAttribute = parameters[i].GetCustomAttribute <XmlElementAttribute>();
                var parameterName    = !string.IsNullOrEmpty(elementAttribute?.ElementName)
                                                                                ? elementAttribute.ElementName
                                                                                : parameters[i].GetCustomAttribute <MessageParameterAttribute>()?.Name ?? parameters[i].Name;
                var parameterNs = elementAttribute?.Namespace ?? operation.Contract.Namespace;

                if (xmlReader.IsStartElement(parameterName, parameterNs))
                {
                    xmlReader.MoveToStartElement(parameterName, parameterNs);

                    if (xmlReader.IsStartElement(parameterName, parameterNs))
                    {
                        var elementType = parameters[i].ParameterType.GetElementType();
                        if (elementType == null || parameters[i].ParameterType.IsArray)
                        {
                            elementType = parameters[i].ParameterType;
                        }

                        switch (_serializer)
                        {
                        case SoapSerializer.XmlSerializer:
                        {
                            // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
                            var serializer = new XmlSerializer(elementType, null, new Type[0], new XmlRootAttribute(parameterName), parameterNs);
                            arguments.Add(serializer.Deserialize(xmlReader));
                        }
                        break;

                        case SoapSerializer.DataContractSerializer:
                        {
                            var serializer = new DataContractSerializer(elementType, parameterName, parameterNs);
                            arguments.Add(serializer.ReadObject(xmlReader, verifyObjectName: true));
                        }
                        break;

                        default: throw new NotImplementedException();
                        }
                    }
                }
                else
                {
                    arguments.Add(null);
                }
            }

            var outParams = operation.DispatchMethod.GetParameters().Where(x => x.IsOut || x.ParameterType.IsByRef).ToArray();

            foreach (var parameterInfo in outParams)
            {
                if (parameterInfo.ParameterType.Name == "Guid&")
                {
                    outArgs[parameterInfo.Name] = Guid.Empty;
                }
                else if (parameterInfo.ParameterType.Name == "String&" || parameterInfo.ParameterType.GetElementType().IsArray)
                {
                    outArgs[parameterInfo.Name] = null;
                }
                else
                {
                    var type = parameterInfo.ParameterType.GetElementType();
                    outArgs[parameterInfo.Name] = Activator.CreateInstance(type);
                }
            }
            return(arguments.ToArray());
        }
Ejemplo n.º 10
0
        private object[] GetRequestArguments(Message requestMessage, System.Xml.XmlDictionaryReader xmlReader, OperationDescription operation)
        {
            var arguments = new object[operation.AllParameters.Length];

            // Find the element for the operation's data
            if (!operation.IsMessageContractRequest)
            {
                xmlReader.ReadStartElement(operation.Name, operation.Contract.Namespace);
            }

            // if any ordering issues, possible to rewrite like:

            /*while (!xmlReader.EOF)
             * {
             *      var parameterInfo = operation.InParameters.FirstOrDefault(p => p.Name == xmlReader.LocalName && p.Namespace == xmlReader.NamespaceURI);
             *      if (parameterInfo == null)
             *      {
             *              xmlReader.Skip();
             *              continue;
             *      }
             *      var parameterName = parameterInfo.Name;
             *      var parameterNs = parameterInfo.Namespace;
             *      ...
             * }*/

            foreach (var parameterInfo in operation.InParameters)
            {
                var parameterName = parameterInfo.Name;
                var parameterNs   = parameterInfo.Namespace;

                if (xmlReader.IsStartElement(parameterName, parameterNs))
                {
                    xmlReader.MoveToStartElement(parameterName, parameterNs);

                    if (xmlReader.IsStartElement(parameterName, parameterNs))
                    {
                        var elementType = parameterInfo.Parameter.ParameterType.GetElementType();
                        if (elementType == null || parameterInfo.Parameter.ParameterType.IsArray)
                        {
                            elementType = parameterInfo.Parameter.ParameterType;
                        }

                        switch (_serializer)
                        {
                        case SoapSerializer.XmlSerializer:
                        {
                            // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
                            var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, parameterName, parameterNs);
                            lock (serializer)
                            {
                                arguments[parameterInfo.Index] = serializer.Deserialize(xmlReader);
                            }
                        }

                        break;

                        case SoapSerializer.DataContractSerializer:
                        {
                            var serializer = new DataContractSerializer(elementType, parameterName, parameterNs);
                            arguments[parameterInfo.Index] = serializer.ReadObject(xmlReader, verifyObjectName: true);
                        }

                        break;

                        default: throw new NotImplementedException();
                        }
                    }
                }
                else
                {
                    arguments[parameterInfo.Index] = null;
                }
            }

            foreach (var parameterInfo in operation.OutParameters)
            {
                if (arguments[parameterInfo.Index] != null)
                {
                    // do not overwrite input ref parameters
                    continue;
                }

                if (parameterInfo.Parameter.ParameterType.Name == "Guid&")
                {
                    arguments[parameterInfo.Index] = Guid.Empty;
                }
                else if (parameterInfo.Parameter.ParameterType.Name == "String&" || parameterInfo.Parameter.ParameterType.GetElementType().IsArray)
                {
                    arguments[parameterInfo.Index] = null;
                }
                else
                {
                    var type = parameterInfo.Parameter.ParameterType.GetElementType();
                    arguments[parameterInfo.Index] = Activator.CreateInstance(type);
                }
            }

            return(arguments);
        }
Ejemplo n.º 11
0
        private object[] GetRequestArguments(Message requestMessage, System.Xml.XmlDictionaryReader xmlReader, OperationDescription operation, HttpContext httpContext)
        {
            var arguments = new object[operation.AllParameters.Length];

            // if any ordering issues, possible to rewrite like:

            /*while (!xmlReader.EOF)
             * {
             *      var parameterInfo = operation.InParameters.FirstOrDefault(p => p.Name == xmlReader.LocalName && p.Namespace == xmlReader.NamespaceURI);
             *      if (parameterInfo == null)
             *      {
             *              xmlReader.Skip();
             *              continue;
             *      }
             *      var parameterName = parameterInfo.Name;
             *      var parameterNs = parameterInfo.Namespace;
             *      ...
             * }*/

            // Find the element for the operation's data
            if (!operation.IsMessageContractRequest)
            {
                xmlReader.ReadStartElement(operation.Name, operation.Contract.Namespace);

                foreach (var parameterInfo in operation.InParameters)
                {
                    var parameterType = parameterInfo.Parameter.ParameterType;

                    if (parameterType == typeof(HttpContext))
                    {
                        arguments[parameterInfo.Index] = httpContext;
                    }
                    else
                    {
                        var argumentValue = _serializerHelper.DeserializeInputParameter(xmlReader, parameterType, parameterInfo.Name, operation.Contract.Namespace, parameterInfo);

                        //fix https://github.com/DigDes/SoapCore/issues/379 (hack, need research)
                        if (argumentValue == null)
                        {
                            argumentValue = _serializerHelper.DeserializeInputParameter(xmlReader, parameterType, parameterInfo.Name, parameterInfo.Namespace, parameterInfo);
                        }

                        arguments[parameterInfo.Index] = argumentValue;
                    }
                }
            }
            else
            {
                // MessageContracts are constrained to having one "InParameter". We can do special logic on
                // for this
                Debug.Assert(operation.InParameters.Length == 1, "MessageContracts are constrained to having one 'InParameter'");

                var parameterInfo = operation.InParameters[0];
                var parameterType = parameterInfo.Parameter.ParameterType;

                var messageContractAttribute = parameterType.GetCustomAttribute <MessageContractAttribute>();

                Debug.Assert(messageContractAttribute != null, "operation.IsMessageContractRequest should be false if this is null");

                var @namespace = parameterInfo.Namespace ?? operation.Contract.Namespace;

                if (messageContractAttribute.IsWrapped && !parameterType.GetMembersWithAttribute <MessageHeaderAttribute>().Any())
                {
                    // It's wrapped so we treat it like normal!
                    arguments[parameterInfo.Index] = _serializerHelper.DeserializeInputParameter(xmlReader, parameterInfo.Parameter.ParameterType, parameterInfo.Name, @namespace, parameterInfo);
                }
                else
                {
                    var messageHeadersMembers = parameterType.GetPropertyOrFieldMembers().Where(x => x.GetCustomAttribute <MessageHeaderAttribute>() != null).ToArray();

                    var wrapperObject = Activator.CreateInstance(parameterInfo.Parameter.ParameterType);

                    for (var i = 0; i < requestMessage.Headers.Count; i++)
                    {
                        var header = requestMessage.Headers[i];
                        var member = messageHeadersMembers.FirstOrDefault(x => x.Name == header.Name);

                        if (member != null)
                        {
                            var messageHeaderAttribute = member.GetCustomAttribute <MessageHeaderAttribute>();
                            var reader = requestMessage.Headers.GetReaderAtHeader(i);

                            var value = _serializerHelper.DeserializeInputParameter(reader, member.GetPropertyOrFieldType(), messageHeaderAttribute.Name ?? member.Name, messageHeaderAttribute.Namespace ?? @namespace);

                            member.SetValueToPropertyOrField(wrapperObject, value);
                        }
                    }

                    // This object isn't a wrapper element, so we will hunt for the nested message body
                    // member inside of it
                    var messageBodyMembers = parameterType.GetPropertyOrFieldMembers().Where(x => x.GetCustomAttribute <MessageBodyMemberAttribute>() != null).Select(mi => new
                    {
                        Member = mi,
                        MessageBodyMemberAttribute = mi.GetCustomAttribute <MessageBodyMemberAttribute>()
                    }).OrderBy(x => x.MessageBodyMemberAttribute.Order);

                    if (messageContractAttribute.IsWrapped)
                    {
                        xmlReader.Read();
                    }

                    foreach (var messageBodyMember in messageBodyMembers)
                    {
                        var messageBodyMemberAttribute = messageBodyMember.MessageBodyMemberAttribute;
                        var messageBodyMemberInfo      = messageBodyMember.Member;

                        var innerParameterName = messageBodyMemberAttribute.Name ?? messageBodyMemberInfo.Name;
                        var innerParameterNs   = messageBodyMemberAttribute.Namespace ?? @namespace;
                        var innerParameterType = messageBodyMemberInfo.GetPropertyOrFieldType();

                        //xmlReader.MoveToStartElement(innerParameterName, innerParameterNs);
                        var innerParameter = _serializerHelper.DeserializeInputParameter(xmlReader, innerParameterType, innerParameterName, innerParameterNs, parameterInfo);

                        messageBodyMemberInfo.SetValueToPropertyOrField(wrapperObject, innerParameter);
                    }

                    arguments[parameterInfo.Index] = wrapperObject;
                }
            }

            foreach (var parameterInfo in operation.OutParameters)
            {
                if (arguments[parameterInfo.Index] != null)
                {
                    // do not overwrite input ref parameters
                    continue;
                }

                if (parameterInfo.Parameter.ParameterType.Name == "Guid&")
                {
                    arguments[parameterInfo.Index] = Guid.Empty;
                }
                else if (parameterInfo.Parameter.ParameterType.Name == "String&" || parameterInfo.Parameter.ParameterType.GetElementType().IsArray)
                {
                    arguments[parameterInfo.Index] = null;
                }
                else
                {
                    var type = parameterInfo.Parameter.ParameterType.GetElementType();
                    arguments[parameterInfo.Index] = Activator.CreateInstance(type);
                }
            }

            return(arguments);
        }
Ejemplo n.º 12
0
        private object[] GetRequestArguments(Message requestMessage, System.Xml.XmlDictionaryReader xmlReader, OperationDescription operation, HttpContext httpContext)
        {
            var arguments = new object[operation.AllParameters.Length];

            // Find the element for the operation's data
            if (!operation.IsMessageContractRequest)
            {
                xmlReader.ReadStartElement(operation.Name, operation.Contract.Namespace);
            }

            // if any ordering issues, possible to rewrite like:

            /*while (!xmlReader.EOF)
             * {
             *      var parameterInfo = operation.InParameters.FirstOrDefault(p => p.Name == xmlReader.LocalName && p.Namespace == xmlReader.NamespaceURI);
             *      if (parameterInfo == null)
             *      {
             *              xmlReader.Skip();
             *              continue;
             *      }
             *      var parameterName = parameterInfo.Name;
             *      var parameterNs = parameterInfo.Namespace;
             *      ...
             * }*/

            foreach (var parameterInfo in operation.InParameters)
            {
                var parameterName = parameterInfo.Name;

                var parameterNs = parameterInfo.Namespace ?? operation.Contract.Namespace;

                if (xmlReader.IsStartElement(parameterName, parameterNs))
                {
                    xmlReader.MoveToStartElement(parameterName, parameterNs);

                    if (xmlReader.IsStartElement(parameterName, parameterNs))
                    {
                        switch (_serializer)
                        {
                        case SoapSerializer.XmlSerializer:
                        {
                            // case [XmlElement("parameter")] int parameter
                            // case int[] parameter
                            // case [XmlArray("parameter")] int[] parameter
                            if (!parameterInfo.Parameter.ParameterType.IsArray || (parameterInfo.ArrayName != null && parameterInfo.ArrayItemName == null))
                            {
                                // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
                                var elementType = parameterInfo.Parameter.ParameterType.GetElementType();
                                if (elementType == null || parameterInfo.Parameter.ParameterType.IsArray)
                                {
                                    elementType = parameterInfo.Parameter.ParameterType;
                                }

                                var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, parameterName, parameterNs);
                                lock (serializer)
                                {
                                    arguments[parameterInfo.Index] = serializer.Deserialize(xmlReader);
                                }
                            }

                            // case [XmlElement("parameter")] int[] parameter
                            // case [XmlArray("parameter"), XmlArrayItem(ElementName = "item")] int[] parameter
                            else
                            {
                                //if (parameterInfo.ArrayItemName != null)
                                {
                                    xmlReader.ReadStartElement(parameterName, parameterNs);
                                }

                                var elementType = parameterInfo.Parameter.ParameterType.GetElementType();

                                var localName = parameterInfo.ArrayItemName ?? elementType.Name;
                                if (parameterInfo.ArrayItemName == null && elementType.Namespace.StartsWith("System"))
                                {
                                    localName = localName.ToLower();
                                }

                                //localName = "ComplexModelInput";
                                var deserializeMethod = typeof(XmlSerializerExtensions)
                                                        .GetGenericMethod(nameof(XmlSerializerExtensions.DeserializeArray), new[] { elementType });
                                var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, localName, parameterNs);
                                lock (serializer)
                                {
                                    arguments[parameterInfo.Index] = deserializeMethod.Invoke(null, new object[] { serializer, localName, parameterNs, xmlReader });
                                }

                                //if (parameterInfo.ArrayItemName != null)
                                {
                                    xmlReader.ReadEndElement();
                                }
                            }
                        }

                        break;

                        case SoapSerializer.DataContractSerializer:
                        {
                            var elementType = parameterInfo.Parameter.ParameterType.GetElementType();
                            if (elementType == null || parameterInfo.Parameter.ParameterType.IsArray)
                            {
                                elementType = parameterInfo.Parameter.ParameterType;
                            }

                            var serializer = new DataContractSerializer(elementType, parameterName, parameterNs);
                            arguments[parameterInfo.Index] = serializer.ReadObject(xmlReader, verifyObjectName: true);
                        }

                        break;

                        default: throw new NotImplementedException();
                        }
                    }
                }
                else if (parameterInfo.Parameter.ParameterType == typeof(HttpContext))
                {
                    arguments[parameterInfo.Index] = httpContext;
                }
                else
                {
                    arguments[parameterInfo.Index] = null;
                }
            }

            foreach (var parameterInfo in operation.OutParameters)
            {
                if (arguments[parameterInfo.Index] != null)
                {
                    // do not overwrite input ref parameters
                    continue;
                }

                if (parameterInfo.Parameter.ParameterType.Name == "Guid&")
                {
                    arguments[parameterInfo.Index] = Guid.Empty;
                }
                else if (parameterInfo.Parameter.ParameterType.Name == "String&" || parameterInfo.Parameter.ParameterType.GetElementType().IsArray)
                {
                    arguments[parameterInfo.Index] = null;
                }
                else
                {
                    var type = parameterInfo.Parameter.ParameterType.GetElementType();
                    arguments[parameterInfo.Index] = Activator.CreateInstance(type);
                }
            }

            return(arguments);
        }